susumu.yata
null+****@clear*****
Tue Nov 24 13:03:43 JST 2015
susumu.yata 2015-11-24 13:03:43 +0900 (Tue, 24 Nov 2015) New Revision: 59c1f04bb8832217517fac08b8cb9359e20abdb0 https://github.com/groonga/groonga/commit/59c1f04bb8832217517fac08b8cb9359e20abdb0 Message: grn_ts: implement grn_ts_cursor Modified files: lib/ts.c lib/ts/ts_cursor.c lib/ts/ts_cursor.h Modified: lib/ts.c (+16 -15) =================================================================== --- lib/ts.c 2015-11-24 13:06:22 +0900 (b797760) +++ lib/ts.c 2015-11-24 13:03:43 +0900 (c718eee) @@ -24,6 +24,7 @@ #include "grn_str.h" #include "ts/ts_buf.h" +#include "ts/ts_cursor.h" #include "ts/ts_expr.h" #include "ts/ts_log.h" #include "ts/ts_str.h" @@ -633,7 +634,8 @@ grn_ts_select_filter(grn_ctx *ctx, grn_obj *table, grn_ts_str str, grn_ts_record **out, size_t *n_out, size_t *n_hits) { grn_rc rc; - grn_table_cursor *cursor; + grn_table_cursor *cursor_obj; + grn_ts_cursor *cursor; grn_ts_expr *expr; grn_ts_record *buf = NULL; size_t buf_size = 0; @@ -642,16 +644,21 @@ grn_ts_select_filter(grn_ctx *ctx, grn_obj *table, grn_ts_str str, *n_out = 0; *n_hits = 0; - cursor = grn_table_cursor_open(ctx, table, NULL, 0, NULL, 0, 0, -1, - GRN_CURSOR_ASCENDING | GRN_CURSOR_BY_ID); - if (!cursor) { + cursor_obj = grn_table_cursor_open(ctx, table, NULL, 0, NULL, 0, 0, -1, + GRN_CURSOR_ASCENDING | GRN_CURSOR_BY_ID); + if (!cursor_obj) { return (ctx->rc != GRN_SUCCESS) ? ctx->rc : GRN_UNKNOWN_ERROR; } + rc = grn_ts_obj_cursor_open(ctx, cursor_obj, &cursor); + if (rc != GRN_SUCCESS) { + grn_obj_close(ctx, cursor_obj); + return rc; + } rc = grn_ts_expr_parse(ctx, table, str, &expr); if (rc == GRN_SUCCESS) { for ( ; ; ) { - size_t i, batch_size; + size_t batch_size; grn_ts_record *batch; /* Extend the record buffer. */ @@ -672,15 +679,9 @@ grn_ts_select_filter(grn_ctx *ctx, grn_obj *table, grn_ts_str str, /* Read records from the cursor. */ batch = buf + *n_out; - for (i = 0; i < GRN_TS_BATCH_SIZE; i++) { - batch[i].id = grn_table_cursor_next(ctx, cursor); - if (batch[i].id == GRN_ID_NIL) { - break; - } - batch[i].score = 0.0; - } - batch_size = i; - if (!batch_size) { + rc = grn_ts_cursor_read(ctx, cursor, batch, GRN_TS_BATCH_SIZE, + &batch_size); + if ((rc != GRN_SUCCESS) || !batch_size) { break; } @@ -716,7 +717,7 @@ grn_ts_select_filter(grn_ctx *ctx, grn_obj *table, grn_ts_str str, grn_ts_expr_close(ctx, expr); } /* Ignore a failure of destruction. */ - grn_table_cursor_close(ctx, cursor); + grn_ts_cursor_close(ctx, cursor); if (rc != GRN_SUCCESS) { if (buf) { Modified: lib/ts/ts_cursor.c (+144 -0) =================================================================== --- lib/ts/ts_cursor.c 2015-11-24 13:06:22 +0900 (676464b) +++ lib/ts/ts_cursor.c 2015-11-24 13:03:43 +0900 (5329571) @@ -17,3 +17,147 @@ */ #include "ts_cursor.h" + +#include "../grn_ctx.h" +#include "../grn_dat.h" +#include "../grn_hash.h" +#include "../grn_pat.h" + +#include "ts_log.h" +#include "ts_util.h" + +/*------------------------------------------------------------- + * grn_ts_obj_cursor. + */ + +typedef struct { + GRN_TS_CURSOR_COMMON_MEMBERS + grn_obj *obj; /* Wrapped cursor object. */ +} grn_ts_obj_cursor; + +grn_rc +grn_ts_obj_cursor_open(grn_ctx *ctx, grn_obj *obj, grn_ts_cursor **cursor) +{ + grn_ts_obj_cursor *new_cursor; + if (!ctx) { + return GRN_INVALID_ARGUMENT; + } + if (!obj || !cursor) { + GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid argument"); + } + switch (obj->header.type) { + case GRN_CURSOR_TABLE_HASH_KEY: + case GRN_CURSOR_TABLE_PAT_KEY: + case GRN_CURSOR_TABLE_DAT_KEY: + case GRN_CURSOR_TABLE_NO_KEY: { + break; + } + default: { + GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid argument"); + } + } + new_cursor = GRN_MALLOCN(grn_ts_obj_cursor, 1); + if (!new_cursor) { + GRN_TS_ERR_RETURN(GRN_NO_MEMORY_AVAILABLE, + "GRN_MALLOCN failed: %" GRN_FMT_SIZE " x 1", + sizeof(grn_ts_obj_cursor)); + } + new_cursor->type = GRN_TS_OBJ_CURSOR; + new_cursor->obj = obj; + *cursor = (grn_ts_cursor *)new_cursor; + return GRN_SUCCESS; +} + +/* grn_ts_obj_cursor_close() destroys a wrapper cursor. */ +static grn_rc +grn_ts_obj_cursor_close(grn_ctx *ctx, grn_ts_obj_cursor *cursor) +{ + if (cursor->obj) { + grn_obj_close(ctx, cursor->obj); + } + GRN_FREE(cursor); + return GRN_SUCCESS; +} + +#define GRN_TS_OBJ_CURSOR_READ(type)\ + size_t i;\ + grn_ ## type ## _cursor *obj = (grn_ ## type ## _cursor *)cursor->obj;\ + for (i = 0; i < max_n_recs; i++) {\ + recs[i].id = grn_ ## type ## _cursor_next(ctx, obj);\ + if (!recs[i].id) {\ + break;\ + }\ + recs[i].score = 0;\ + }\ + *n_recs = i;\ + return GRN_SUCCESS; +/* grn_ts_obj_cursor_read() reads records from a wrapper cursor. */ +static grn_rc +grn_ts_obj_cursor_read(grn_ctx *ctx, grn_ts_obj_cursor *cursor, + grn_ts_record *recs, size_t max_n_recs, size_t *n_recs) +{ + switch (cursor->obj->header.type) { + case GRN_CURSOR_TABLE_HASH_KEY: { + GRN_TS_OBJ_CURSOR_READ(hash) + } + case GRN_CURSOR_TABLE_PAT_KEY: { + GRN_TS_OBJ_CURSOR_READ(pat) + } + case GRN_CURSOR_TABLE_DAT_KEY: { + GRN_TS_OBJ_CURSOR_READ(dat) + } + case GRN_CURSOR_TABLE_NO_KEY: { + GRN_TS_OBJ_CURSOR_READ(array) + } + default: { + GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid argument"); + } + } + return GRN_SUCCESS; +} + +/*------------------------------------------------------------- + * grn_ts_cursor. + */ + +grn_rc +grn_ts_cursor_close(grn_ctx *ctx, grn_ts_cursor *cursor) +{ + if (!ctx) { + return GRN_INVALID_ARGUMENT; + } + if (!cursor) { + GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid argument"); + } + switch (cursor->type) { + case GRN_TS_OBJ_CURSOR: { + return grn_ts_obj_cursor_close(ctx, (grn_ts_obj_cursor *)cursor); + } + default: { + GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid cursor type: %d", + cursor->type); + } + } +} + +grn_rc +grn_ts_cursor_read(grn_ctx *ctx, grn_ts_cursor *cursor, + grn_ts_record *out, size_t max_n_out, size_t *n_out) +{ + if (!ctx) { + return GRN_INVALID_ARGUMENT; + } + if (!cursor || (!out && max_n_out) || !n_out) { + GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid argument"); + } + switch (cursor->type) { + case GRN_TS_OBJ_CURSOR: { + return grn_ts_obj_cursor_read(ctx, (grn_ts_obj_cursor *)cursor, + out, max_n_out, n_out); + } + default: { + GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid cursor type: %d", + cursor->type); + } + } +} Modified: lib/ts/ts_cursor.h (+13 -7) =================================================================== --- lib/ts/ts_cursor.h 2015-11-24 13:06:22 +0900 (56320df) +++ lib/ts/ts_cursor.h 2015-11-24 13:03:43 +0900 (65bc0fd) @@ -28,18 +28,24 @@ extern "C" { #endif typedef enum { - GRN_TS_HASH_CURSOR, - GRN_TS_PAT_CURSOR, - GRN_TS_DAT_CURSOR, - GRN_TS_ARRAY_CURSOR + GRN_TS_OBJ_CURSOR /* Wrapper cursor. */ } grn_ts_cursor_type; +#define GRN_TS_CURSOR_COMMON_MEMBERS\ + grn_ts_cursor_type type; /* Cursor type. */ + typedef struct { - grn_ts_cursor_type type; + GRN_TS_CURSOR_COMMON_MEMBERS } grn_ts_cursor; -/* grn_ts_cursor_open() creates a cursor. */ -grn_rc grn_ts_cursor_open(grn_ctx *ctx, grn_ts_cursor **cursor); +/* + * grn_ts_obj_cursor_open() creates a wrapper cursor. + * The new cursor will be a wrapper for a Groonga cursor specified by `obj`. + * On success, `obj` will be closed in grn_ts_cursor_close(). + * On failure, `obj` is left as is. + */ +grn_rc grn_ts_obj_cursor_open(grn_ctx *ctx, grn_obj *obj, + grn_ts_cursor **cursor); /* grn_ts_cursor_close() destroys a cursor. */ grn_rc grn_ts_cursor_close(grn_ctx *ctx, grn_ts_cursor *cursor); -------------- next part -------------- HTML����������������������������...다운로드