null+****@clear*****
null+****@clear*****
2010年 8月 26日 (木) 15:15:46 JST
Daijiro MORI 2010-08-26 06:15:46 +0000 (Thu, 26 Aug 2010) New Revision: 10f39f37a64bd52c2d35ff8a7e2209093ae30db6 Log: Enhanced func_suggest_preparer(). Modified files: modules/suggest/suggest.c Modified: modules/suggest/suggest.c (+93 -20) =================================================================== --- modules/suggest/suggest.c 2010-08-25 10:46:51 +0000 (6d30b65) +++ modules/suggest/suggest.c 2010-08-26 06:15:46 +0000 (085e09d) @@ -16,6 +16,7 @@ #include "db.h" #include "ii.h" +#include "token.h" #include "output.h" #include <string.h> @@ -177,28 +178,100 @@ exit: static grn_obj * func_suggest_preparer(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data) { + int r = 0; grn_obj *obj; - if (nargs == 5) { - grn_obj buf, *item = args[2], *seq = args[3]; - grn_id id = GRN_UINT32_VALUE(args[0]); - grn_id type = GRN_UINT32_VALUE(args[1]); - int64_t time = GRN_TIME_VALUE(args[4]); - grn_obj *items = grn_ctx_at(ctx, GRN_OBJ_GET_DOMAIN(item)); - grn_obj *freq = grn_obj_column(ctx, items, CONST_STR_LEN("freq")); - grn_obj *seqs = grn_ctx_at(ctx, GRN_OBJ_GET_DOMAIN(seq)); - grn_obj *events = grn_obj_column(ctx, seqs, CONST_STR_LEN("events")); - GRN_UINT32_INIT(&buf, 0); - GRN_UINT32_SET(ctx, &buf, 1); - grn_obj_set_value(ctx, freq, GRN_RECORD_VALUE(item), &buf, GRN_OBJ_INCR); - GRN_OBJ_FIN(ctx, &buf); - GRN_RECORD_INIT(&buf, 0, grn_obj_get_range(ctx, events)); - GRN_RECORD_SET(ctx, &buf, id); - grn_obj_set_value(ctx, events, GRN_RECORD_VALUE(seq), &buf, GRN_OBJ_APPEND); - GRN_OBJ_FIN(ctx, &buf); - } - if ((obj = GRN_PROC_ALLOC(GRN_DB_UINT32, 0))) { - GRN_UINT32_SET(ctx, obj, 0); + if (nargs == 6) { + grn_obj v1, pre_events; + grn_id post_event = GRN_RECORD_VALUE(args[0]); + grn_id post_type = GRN_RECORD_VALUE(args[1]); + grn_id post_item = GRN_RECORD_VALUE(args[2]); + grn_id seq = GRN_RECORD_VALUE(args[3]); + int64_t post_time = GRN_TIME_VALUE(args[4]); + grn_obj *pairs = args[5]; + grn_obj *items = grn_ctx_at(ctx, GRN_OBJ_GET_DOMAIN(args[2])); + grn_obj *items_freq = grn_obj_column(ctx, items, CONST_STR_LEN("freq")); + grn_obj *items_last = grn_obj_column(ctx, items, CONST_STR_LEN("last")); + grn_obj *seqs = grn_ctx_at(ctx, GRN_OBJ_GET_DOMAIN(args[3])); + grn_obj *seqs_events = grn_obj_column(ctx, seqs, CONST_STR_LEN("events")); + grn_obj *events = grn_ctx_at(ctx, grn_obj_get_range(ctx, seqs_events)); + grn_obj *events_type = grn_obj_column(ctx, events, CONST_STR_LEN("type")); + grn_obj *events_time = grn_obj_column(ctx, events, CONST_STR_LEN("time")); + grn_obj *events_item = grn_obj_column(ctx, events, CONST_STR_LEN("item")); + grn_obj *pairs_pre = grn_obj_column(ctx, pairs, CONST_STR_LEN("pre")); + grn_obj *pairs_post = grn_obj_column(ctx, pairs, CONST_STR_LEN("post")); + grn_obj *pairs_freq0 = grn_obj_column(ctx, pairs, CONST_STR_LEN("freq0")); + grn_obj *pairs_freq1 = grn_obj_column(ctx, pairs, CONST_STR_LEN("freq1")); + grn_obj *pairs_freq2 = grn_obj_column(ctx, pairs, CONST_STR_LEN("freq2")); + GRN_UINT32_INIT(&v1, 0); + GRN_UINT32_SET(ctx, &v1, 1); + GRN_RECORD_INIT(&pre_events, 0, grn_obj_id(ctx, events)); + grn_obj_set_value(ctx, items_freq, post_item, &v1, GRN_OBJ_INCR); + grn_obj_set_value(ctx, items_last, post_item, args[4], GRN_OBJ_SET); + if (post_type) { + int added; + grn_id pid, tid, *ep, *es; + grn_obj pre_type, pre_time, pre_item; + uint64_t key, key_ = ((uint64_t)post_item) << 32; + grn_obj_get_value(ctx, seqs_events, seq, &pre_events); + ep = (grn_id *)GRN_BULK_CURR(&pre_events); + es = (grn_id *)GRN_BULK_HEAD(&pre_events); + GRN_RECORD_INIT(&pre_type, 0, grn_obj_get_range(ctx, events_type)); + GRN_TIME_INIT(&pre_time, 0); + GRN_RECORD_INIT(&pre_item, 0, grn_obj_get_range(ctx, events_item)); + while (es < ep--) { + GRN_BULK_REWIND(&pre_type); + GRN_BULK_REWIND(&pre_time); + GRN_BULK_REWIND(&pre_item); + grn_obj_get_value(ctx, events_type, *ep, &pre_type); + grn_obj_get_value(ctx, events_time, *ep, &pre_time); + grn_obj_get_value(ctx, events_item, *ep, &pre_item); + if (GRN_TIME_VALUE(&pre_time) + 60000000 < post_time) { + r = (int)((post_time - GRN_TIME_VALUE(&pre_time))/1000000); + break; + } + key = key_ + GRN_RECORD_VALUE(&pre_item); + pid = grn_table_add(ctx, pairs, &key, sizeof(uint64_t), &added); + if (added) { + grn_obj_set_value(ctx, pairs_pre, pid, &pre_item, GRN_OBJ_SET); + grn_obj_set_value(ctx, pairs_post, pid, args[2], GRN_OBJ_SET); + } + if (GRN_RECORD_VALUE(&pre_type)) { + grn_obj_set_value(ctx, pairs_freq1, pid, &v1, GRN_OBJ_INCR); + break; + } else { + grn_obj_set_value(ctx, pairs_freq0, pid, &v1, GRN_OBJ_INCR); + } + } + { + char keybuf[GRN_TABLE_MAX_KEY_SIZE]; + int keylen = grn_table_get_key(ctx, items, post_item, + keybuf, GRN_TABLE_MAX_KEY_SIZE); + grn_token *token = grn_token_open(ctx, items, keybuf, keylen, 1); + if (token) { + while ((tid = grn_token_next(ctx, token)) && tid != post_item) { + key = key_ + tid; + pid = grn_table_add(ctx, pairs, &key, sizeof(uint64_t), &added); + if (added) { + GRN_RECORD_SET(ctx, &pre_item, tid); + grn_obj_set_value(ctx, pairs_pre, pid, &pre_item, GRN_OBJ_SET); + grn_obj_set_value(ctx, pairs_post, pid, args[2], GRN_OBJ_SET); + } + grn_obj_set_value(ctx, pairs_freq2, pid, &v1, GRN_OBJ_INCR); + } + grn_token_close(ctx, token); + } + } + GRN_OBJ_FIN(ctx, &pre_type); + GRN_OBJ_FIN(ctx, &pre_time); + GRN_OBJ_FIN(ctx, &pre_item); + GRN_BULK_REWIND(&pre_events); + } + GRN_RECORD_SET(ctx, &pre_events, post_event); + grn_obj_set_value(ctx, seqs_events, seq, &pre_events, GRN_OBJ_APPEND); + GRN_OBJ_FIN(ctx, &pre_events); + GRN_OBJ_FIN(ctx, &v1); } + if ((obj = GRN_PROC_ALLOC(GRN_DB_UINT32, 0))) { GRN_UINT32_SET(ctx, obj, r); } return obj; }