[Groonga-commit] groonga/groonga [master] added grn_dat_lcp_search() and grn_dat_next().

Back to archive index

null+****@clear***** null+****@clear*****
2011年 12月 27日 (火) 10:51:18 JST


Susumu Yata	2011-12-27 10:51:18 +0900 (Tue, 27 Dec 2011)

  New Revision: ec70abc63822d37e595f9ad3645ed9d8d85098b8

  Log:
    added grn_dat_lcp_search() and grn_dat_next().

  Modified files:
    lib/dat.cpp
    lib/dat.h

  Modified: lib/dat.cpp (+48 -0)
===================================================================
--- lib/dat.cpp    2011-12-27 10:07:13 +0900 (4aa8ac1)
+++ lib/dat.cpp    2011-12-27 10:51:18 +0900 (812e34e)
@@ -612,6 +612,36 @@ grn_dat_update(grn_ctx *ctx, grn_dat *dat,
   return GRN_SUCCESS;
 }
 
+grn_id
+grn_dat_lcp_search(grn_ctx *ctx, grn_dat *dat,
+                   const void *key, unsigned int key_size)
+{
+  if (!grn_dat_open_trie_if_needed(ctx, dat) || !key ||
+      !(dat->obj.header.flags & GRN_OBJ_KEY_VAR_SIZE)) {
+    return GRN_ID_NIL;
+  }
+
+  grn::dat::Trie * const trie = static_cast<grn::dat::Trie *>(dat->trie);
+  if (!trie) {
+    return GRN_ID_NIL;
+  }
+
+  try {
+    grn::dat::Cursor * const cursor = grn::dat::CursorFactory::open(*trie,
+        NULL, 0, key, key_size, 0, 1,
+        grn::dat::PREFIX_CURSOR | grn::dat::DESCENDING_CURSOR);
+    // grn::dat::PrefixCursor::next() is assumed not to throw an exception.
+    const grn::dat::Key &lcp_key = cursor->next();
+    delete cursor;
+    // The `lcp_key' is still valid even after the cursor deletion.
+    return lcp_key.is_valid() ? lcp_key.id() : GRN_ID_NIL;
+  } catch (const grn::dat::Exception &ex) {
+    ERR(grn_dat_translate_error_code(ex.code()),
+        const_cast<char *>("grn::dat::PrefixCursor::open failed"));
+    return GRN_ID_NIL;
+  }
+}
+
 unsigned int
 grn_dat_size(grn_ctx *ctx, grn_dat *dat)
 {
@@ -828,6 +858,24 @@ _grn_dat_key(grn_ctx *ctx, grn_dat *dat, grn_id id, uint32_t *key_size)
 }
 
 grn_id
+grn_dat_next(grn_ctx *ctx, grn_dat *dat, grn_id id)
+{
+  if (!grn_dat_open_trie_if_needed(ctx, dat)) {
+    return GRN_ID_NIL;
+  }
+  const grn::dat::Trie * const trie = static_cast<grn::dat::Trie *>(dat->trie);
+  if (!trie) {
+    return GRN_ID_NIL;
+  }
+  while (id < trie->max_key_id()) {
+    if (trie->ith_key(++id).is_valid()) {
+      return id;
+    }
+  }
+  return GRN_ID_NIL;
+}
+
+grn_id
 grn_dat_at(grn_ctx *ctx, grn_dat *dat, grn_id id)
 {
   if (!grn_dat_open_trie_if_needed(ctx, dat)) {

  Modified: lib/dat.h (+4 -0)
===================================================================
--- lib/dat.h    2011-12-27 10:07:13 +0900 (cf4fd77)
+++ lib/dat.h    2011-12-27 10:51:18 +0900 (5d028cb)
@@ -54,11 +54,15 @@ struct _grn_dat_cursor {
   grn_id curr_rec;
 };
 
+grn_id grn_dat_lcp_search(grn_ctx *ctx, grn_dat *dat,
+                          const void *key, unsigned int key_size);
+
 grn_id grn_dat_curr_id(grn_ctx *ctx, grn_dat *dat);
 
 grn_rc grn_dat_truncate(grn_ctx *ctx, grn_dat *dat);
 
 const char *_grn_dat_key(grn_ctx *ctx, grn_dat *dat, grn_id id, uint32_t *key_size);
+grn_id grn_dat_next(grn_ctx *ctx, grn_dat *dat, grn_id id);
 grn_id grn_dat_at(grn_ctx *ctx, grn_dat *dat, grn_id id);
 
 #ifdef __cplusplus




Groonga-commit メーリングリストの案内
Back to archive index