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
33typedef struct {
34 GRN_TS_CURSOR_COMMON_MEMBERS
35 grn_obj *obj; /* Wrapped cursor object. */
36} grn_ts_obj_cursor;
37
38grn_rc
39grn_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. */
72static grn_rc
73grn_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. */
95static grn_rc
96grn_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
123grn_rc
124grn_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
143grn_rc
144grn_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