null+****@clear*****
null+****@clear*****
2010年 8月 18日 (水) 23:17:04 JST
Daijiro MORI 2010-08-18 14:17:04 +0000 (Wed, 18 Aug 2010) New Revision: 520e95c7d954a4efbb5694b0978f9996e23c4165 Log: Fixed a memory leak bug and enhanced error handling in build_index(). Modified files: lib/db.c Modified: lib/db.c (+36 -32) =================================================================== --- lib/db.c 2010-08-18 12:17:46 +0000 (6513261) +++ lib/db.c 2010-08-18 14:17:04 +0000 (aec0c93) @@ -4889,42 +4889,46 @@ exit : static void build_index(grn_ctx *ctx, grn_obj *obj) { - int i, ncol; - grn_id id, *s; grn_table_cursor *tc; - grn_obj *src, *src_dom, **cp, **col, rv; - s = DB_OBJ(obj)->source; - src = grn_ctx_at(ctx, *s); - if (GRN_OBJ_TABLEP(src)) { - src_dom = src; - } else { - src_dom = grn_ctx_at(ctx, src->header.domain); - } - if (!src_dom) { ERR(GRN_INVALID_ARGUMENT, "domain invalid"); } - ncol = DB_OBJ(obj)->source_size / sizeof(grn_id); - col = GRN_MALLOC(ncol * sizeof(grn_obj)); - cp = col; - for (i=0; i < ncol; i++, s++, col++) { - *col = grn_ctx_at(ctx, *s); - if (!*col) { ERR(GRN_INVALID_ARGUMENT, "source invalid, n=%d",i); } - } - col = cp; - tc = grn_table_cursor_open(ctx, src_dom, NULL, 0, NULL, 0, 0, -1, GRN_CURSOR_BY_ID); - GRN_TEXT_INIT(&rv, 0); - while ((id = grn_table_cursor_next(ctx, tc)) != GRN_ID_NIL) { - for (i = 0; i < ncol; i++, col++) { - GRN_BULK_REWIND(&rv); - if (GRN_OBJ_TABLEP(*col)) { - grn_table_get_key2(ctx, *col, id, &rv); - } else { - grn_obj_get_value(ctx, *col, id, &rv); + grn_obj *src, **cp, **col, *target, rv; + grn_id id, *s = DB_OBJ(obj)->source; + if (!(DB_OBJ(obj)->source_size) || !s) { return; } + if ((src = grn_ctx_at(ctx, *s))) { + if ((target = GRN_OBJ_TABLEP(src) ? src : grn_ctx_at(ctx, src->header.domain))) { + int i, ncol = DB_OBJ(obj)->source_size / sizeof(grn_id); + if ((col = GRN_MALLOC(ncol * sizeof(grn_obj *)))) { + for (cp = col, i = ncol; i; s++, cp++, i--) { + if (!(*cp = grn_ctx_at(ctx, *s))) { + ERR(GRN_INVALID_ARGUMENT, "source invalid, n=%d",i); + GRN_FREE(col); + return; + } + } + if ((tc = grn_table_cursor_open(ctx, target, NULL, 0, NULL, 0, + 0, -1, GRN_CURSOR_BY_ID))) { + GRN_TEXT_INIT(&rv, 0); + while ((id = grn_table_cursor_next(ctx, tc)) != GRN_ID_NIL) { + for (cp = col, i = ncol; i; i--, cp++) { + GRN_BULK_REWIND(&rv); + if (GRN_OBJ_TABLEP(*cp)) { + grn_table_get_key2(ctx, *cp, id, &rv); + } else { + grn_obj_get_value(ctx, *cp, id, &rv); + } + call_hook_for_build(ctx, *cp, id, &rv, 0); + } + } + GRN_OBJ_FIN(ctx, &rv); + grn_table_cursor_close(ctx, tc); + } + GRN_FREE(col); } - call_hook_for_build(ctx, *col, id, &rv, 0); + } else { + ERR(GRN_INVALID_ARGUMENT, "invalid target"); } - col = cp; + } else { + ERR(GRN_INVALID_ARGUMENT, "invalid source"); } - GRN_OBJ_FIN(ctx, &rv); - grn_table_cursor_close(ctx, tc); } static void