Uploaded image for project: 'WiredTiger'
  1. WiredTiger
  2. WT-1723

WT_CURSOR::search() returned WT_NOTFOUND when 'suffix' index key collator is used

    • Type: Icon: Task Task
    • Resolution: Done
    • WT2.5.3
    • Affects Version/s: None
    • Component/s: None
    • Labels:

      Hi!

      I've written a custom collator for index that effectively compares only suffixes of the keys.
      The problem is that now

      Unable to find source-code formatter for language: wt_cursor. Available languages are: actionscript, ada, applescript, bash, c, c#, c++, cpp, css, erlang, go, groovy, haskell, html, java, javascript, js, json, lua, none, nyan, objc, perl, php, python, r, rainbow, ruby, scala, sh, sql, swift, visualbasic, xml, yaml
      ::search()

      in index returns

      Unable to find source-code formatter for language: wt_notfound```. Available languages are: actionscript, ada, applescript, bash, c, c#, c++, cpp, css, erlang, go, groovy, haskell, html, java, javascript, js, json, lua, none, nyan, objc, perl, php, python, r, rainbow, ruby, scala, sh, sql, swift, visualbasic, xml, yaml
       for key that is equal according to the collator, but has different prefix.
      
      Minimized test:
      

      include <assert.h>

      include <stdio.h>

      include <stdlib.h>

      include <string.h>

      include <wiredtiger.h>

      define WT_HOME "index_suff_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
      compare_ikey(const WT_ITEM _a, const WT_ITEM _b)
      {
      assert(a->size == 2);
      assert(b->size == 2);
      int av = ((char*)a->data)[1],
      bv = ((char*)b->data)[1];
      return compare_int(av, bv);
      }

      static int
      compare_pkey(const WT_ITEM _a, const WT_ITEM _b)
      {
      assert(a->size == 1);
      assert(b->size == 1);
      int av = ((char*)a->data)[0],
      bv = ((char*)b->data)[0];
      return compare_int(av, bv);
      }

      static int
      main_compare(WT_COLLATOR _collator, WT_SESSION _session, const WT_ITEM *key1, const WT_ITEM _key2, int _cmp)
      {
      *cmp = compare_pkey(key1, key2);
      return 0;
      }

      static int
      index_compare(WT_COLLATOR _collator, WT_SESSION _session, const WT_ITEM *key1, const WT_ITEM _key2, int _cmp)
      {
      WT_ITEM ikey1, pkey1, ikey2, pkey2;

      WT_CALL(wiredtiger_struct_unpack(session, key1->data, key1->size, "uu", &ikey1, &pkey1));
      WT_CALL(wiredtiger_struct_unpack(session, key2->data, key2->size, "uu", &ikey2, &pkey2));

      if ((*cmp = compare_ikey(&ikey1, &ikey2)) != 0)
      return 0;

      if ((pkey1.size > 0) && (pkey2.size > 0))
      *cmp = compare_pkey(&pkey1, &pkey2);

      return 0;
      }

      static WT_COLLATOR main_coll =

      { main_compare, NULL, NULL }

      ;
      static WT_COLLATOR index_coll =

      { index_compare, NULL, NULL }

      ;

      int
      main(void)

      { WT_CONNECTION *conn; WT_SESSION *session; WT_CURSOR *cursor; char kbuf, vbuf[2]; WT_ITEM ki, vi, iki; 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, "main_coll", &main_coll, NULL)); WT_CALL(conn->add_collator(conn, "index_coll", &index_coll, NULL)); WT_CALL(session->create(session, "table:main", "key_format=u,value_format=u,columns=(k,v),collator=main_coll")); WT_CALL(session->create(session, "index:main:index", "columns=(v),collator=index_coll")); WT_CALL(session->open_cursor(session, "table:main", NULL, NULL, &cursor)); kbuf = 'a'; ki.data = &kbuf; ki.size = sizeof(kbuf); cursor->set_key(cursor, &ki); vbuf[0] = 'b'; vbuf[1] = 'c'; vi.data = &vbuf; vi.size = sizeof(vbuf); cursor->set_value(cursor, &vi); WT_CALL(cursor->insert(cursor)); WT_CALL(cursor->close(cursor)); WT_CALL(session->open_cursor(session, "index:main:index(k,v)", NULL, NULL, &cursor)); vbuf[0] = 'x'; vbuf[1] = 'c'; iki.data = &vbuf; iki.size = sizeof(vbuf); cursor->set_key(cursor, &iki); WT_CALL(cursor->search(cursor)); WT_CALL(cursor->get_key(cursor, &iki)); WT_CALL(cursor->get_value(cursor, &ki, &vi)); printf("found: ikey = '%.2s', key = '%c', value = '%.2s'\n", (char_)iki.data, _(char_)ki.data, (char_)vi.data); WT_CALL(cursor->close(cursor)); WT_CALL(conn->close(conn, NULL)); return 0; } {code}

      When running it I get:

      
      

      $ ./index_suff_collator
      cursor->search(cursor) at (index_suff_collator.c:116) failed: WT_NOTFOUND: item not found [-31803]
      `

      Please advise!
      Thanks!

            Assignee:
            donald.anderson@mongodb.com Donald Anderson
            Reporter:
            dmitri-shubin Dmitri Shubin
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved: