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;
}