1 | /* -*- c-basic-offset: 2 -*- */ |
2 | /* |
3 | Copyright(C) 2015 Brazil |
4 | |
5 | This library is free software; you can redistribute it and/or |
6 | modify it under the terms of the GNU Lesser General Public |
7 | License version 2.1 as published by the Free Software Foundation. |
8 | |
9 | This library is distributed in the hope that it will be useful, |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
12 | Lesser General Public License for more details. |
13 | |
14 | You should have received a copy of the GNU Lesser General Public |
15 | License along with this library; if not, write to the Free Software |
16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
17 | */ |
18 | |
19 | #include "ts_cursor.h" |
20 | |
21 | #include "../grn_ctx.h" |
22 | #include "../grn_dat.h" |
23 | #include "../grn_hash.h" |
24 | #include "../grn_pat.h" |
25 | |
26 | #include "ts_log.h" |
27 | #include "ts_util.h" |
28 | |
29 | /*------------------------------------------------------------- |
30 | * grn_ts_obj_cursor. |
31 | */ |
32 | |
33 | typedef struct { |
34 | GRN_TS_CURSOR_COMMON_MEMBERS |
35 | grn_obj *obj; /* Wrapped cursor object. */ |
36 | } grn_ts_obj_cursor; |
37 | |
38 | grn_rc |
39 | grn_ts_obj_cursor_open(grn_ctx *ctx, grn_obj *obj, grn_ts_cursor **cursor) |
40 | { |
41 | grn_ts_obj_cursor *new_cursor; |
42 | if (!ctx) { |
43 | return GRN_INVALID_ARGUMENT; |
44 | } |
45 | if (!obj || !cursor) { |
46 | GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid argument" ); |
47 | } |
48 | switch (obj->header.type) { |
49 | case GRN_CURSOR_TABLE_HASH_KEY: |
50 | case GRN_CURSOR_TABLE_PAT_KEY: |
51 | case GRN_CURSOR_TABLE_DAT_KEY: |
52 | case GRN_CURSOR_TABLE_NO_KEY: { |
53 | break; |
54 | } |
55 | default: { |
56 | GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid argument" ); |
57 | } |
58 | } |
59 | new_cursor = GRN_MALLOCN(grn_ts_obj_cursor, 1); |
60 | if (!new_cursor) { |
61 | GRN_TS_ERR_RETURN(GRN_NO_MEMORY_AVAILABLE, |
62 | "GRN_MALLOCN failed: %" GRN_FMT_SIZE " x 1" , |
63 | sizeof(grn_ts_obj_cursor)); |
64 | } |
65 | new_cursor->type = GRN_TS_OBJ_CURSOR; |
66 | new_cursor->obj = obj; |
67 | *cursor = (grn_ts_cursor *)new_cursor; |
68 | return GRN_SUCCESS; |
69 | } |
70 | |
71 | /* grn_ts_obj_cursor_close() destroys a wrapper cursor. */ |
72 | static grn_rc |
73 | grn_ts_obj_cursor_close(grn_ctx *ctx, grn_ts_obj_cursor *cursor) |
74 | { |
75 | if (cursor->obj) { |
76 | grn_obj_close(ctx, cursor->obj); |
77 | } |
78 | GRN_FREE(cursor); |
79 | return GRN_SUCCESS; |
80 | } |
81 | |
82 | #define GRN_TS_OBJ_CURSOR_READ(type)\ |
83 | size_t i;\ |
84 | grn_ ## type ## _cursor *obj = (grn_ ## type ## _cursor *)cursor->obj;\ |
85 | for (i = 0; i < max_n_recs; i++) {\ |
86 | recs[i].id = grn_ ## type ## _cursor_next(ctx, obj);\ |
87 | if (!recs[i].id) {\ |
88 | break;\ |
89 | }\ |
90 | recs[i].score = 0;\ |
91 | }\ |
92 | *n_recs = i;\ |
93 | return GRN_SUCCESS; |
94 | /* grn_ts_obj_cursor_read() reads records from a wrapper cursor. */ |
95 | static grn_rc |
96 | grn_ts_obj_cursor_read(grn_ctx *ctx, grn_ts_obj_cursor *cursor, |
97 | grn_ts_record *recs, size_t max_n_recs, size_t *n_recs) |
98 | { |
99 | switch (cursor->obj->header.type) { |
100 | case GRN_CURSOR_TABLE_HASH_KEY: { |
101 | GRN_TS_OBJ_CURSOR_READ(hash) |
102 | } |
103 | case GRN_CURSOR_TABLE_PAT_KEY: { |
104 | GRN_TS_OBJ_CURSOR_READ(pat) |
105 | } |
106 | case GRN_CURSOR_TABLE_DAT_KEY: { |
107 | GRN_TS_OBJ_CURSOR_READ(dat) |
108 | } |
109 | case GRN_CURSOR_TABLE_NO_KEY: { |
110 | GRN_TS_OBJ_CURSOR_READ(array) |
111 | } |
112 | default: { |
113 | GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid argument" ); |
114 | } |
115 | } |
116 | return GRN_SUCCESS; |
117 | } |
118 | |
119 | /*------------------------------------------------------------- |
120 | * grn_ts_cursor. |
121 | */ |
122 | |
123 | grn_rc |
124 | grn_ts_cursor_close(grn_ctx *ctx, grn_ts_cursor *cursor) |
125 | { |
126 | if (!ctx) { |
127 | return GRN_INVALID_ARGUMENT; |
128 | } |
129 | if (!cursor) { |
130 | GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid argument" ); |
131 | } |
132 | switch (cursor->type) { |
133 | case GRN_TS_OBJ_CURSOR: { |
134 | return grn_ts_obj_cursor_close(ctx, (grn_ts_obj_cursor *)cursor); |
135 | } |
136 | default: { |
137 | GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid cursor type: %d" , |
138 | cursor->type); |
139 | } |
140 | } |
141 | } |
142 | |
143 | grn_rc |
144 | grn_ts_cursor_read(grn_ctx *ctx, grn_ts_cursor *cursor, |
145 | grn_ts_record *out, size_t max_n_out, size_t *n_out) |
146 | { |
147 | if (!ctx) { |
148 | return GRN_INVALID_ARGUMENT; |
149 | } |
150 | if (!cursor || (!out && max_n_out) || !n_out) { |
151 | GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid argument" ); |
152 | } |
153 | switch (cursor->type) { |
154 | case GRN_TS_OBJ_CURSOR: { |
155 | return grn_ts_obj_cursor_read(ctx, (grn_ts_obj_cursor *)cursor, |
156 | out, max_n_out, n_out); |
157 | } |
158 | default: { |
159 | GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid cursor type: %d" , |
160 | cursor->type); |
161 | } |
162 | } |
163 | } |
164 | |