Groonga 3.0.9 Source Code Document
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
ctx.h
Go to the documentation of this file.
1 /* -*- c-basic-offset: 2 -*- */
2 /*
3  Copyright(C) 2009-2013 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 #ifndef GRN_CTX_H
19 #define GRN_CTX_H
20 
21 #ifndef GROONGA_IN_H
22 #include "groonga_in.h"
23 #endif /* GROONGA_IN_H */
24 
25 #ifdef HAVE_ERRNO_H
26 #include <errno.h>
27 #endif /* HAVE_ERRNO_H */
28 
29 #ifdef HAVE_SIGNAL_H
30 #include <signal.h>
31 #define GRN_BREAK_POINT raise(SIGTRAP)
32 #endif /* HAVE_SIGNAL_H */
33 
34 #ifdef HAVE_EXECINFO_H
35 #include <execinfo.h>
36 #endif /* HAVE_EXECINFO_H */
37 
38 #ifndef GRN_IO_H
39 #include "io.h"
40 #endif /* GRN_IO_H */
41 
42 #ifdef __cplusplus
43 extern "C" {
44 #endif
45 
46 /**** api in/out ****/
47 
48 #define GRN_API_ENTER do {\
49  if ((ctx)->seqno & 1) {\
50  (ctx)->subno++;\
51  } else {\
52  (ctx)->errlvl = GRN_OK;\
53  (ctx)->rc = GRN_SUCCESS;\
54  (ctx)->seqno++;\
55  }\
56  GRN_TEST_YIELD();\
57 } while (0)
58 
59 /* CAUTION!! : pass only variables or constants as r */
60 #define GRN_API_RETURN(r) do {\
61  if (ctx->subno) {\
62  ctx->subno--;\
63  } else {\
64  ctx->seqno++;\
65  }\
66  GRN_TEST_YIELD();\
67  return r;\
68 } while (0)
69 
70 /**** error handling ****/
71 
72 #define GRN_OP_T0LVL 0
73 #define GRN_OP_ERR0 1
74 
75 #define GRN_EMERG GRN_LOG_EMERG
76 #define GRN_ALERT GRN_LOG_ALERT
77 #define GRN_CRIT GRN_LOG_CRIT
78 #define GRN_ERROR GRN_LOG_ERROR
79 #define GRN_WARN GRN_LOG_WARNING
80 #define GRN_OK GRN_LOG_NOTICE
81 
82 #define ERRCLR(ctx) do {\
83  if (ctx) {\
84  ((grn_ctx *)ctx)->errlvl = GRN_OK;\
85  ((grn_ctx *)ctx)->rc = GRN_SUCCESS;\
86  }\
87  errno = 0;\
88  grn_gctx.errlvl = GRN_OK;\
89  grn_gctx.rc = GRN_SUCCESS;\
90 } while (0)
91 
92 #ifdef HAVE_BACKTRACE
93 #define BACKTRACE(ctx) ((ctx)->ntrace = (unsigned char)backtrace((ctx)->trace, 16))
94 #else /* HAVE_BACKTRACE */
95 #define BACKTRACE(ctx)
96 #endif /* HAVE_BACKTRACE */
97 
101 
102 #ifdef HAVE_BACKTRACE
103 #define LOGTRACE(ctx,lvl) do {\
104  int i;\
105  char **p;\
106  BACKTRACE(ctx);\
107  p = backtrace_symbols((ctx)->trace, (ctx)->ntrace);\
108  for (i = 0; i < (ctx)->ntrace; i++) {\
109  GRN_LOG((ctx), lvl, "%s", p[i]);\
110  }\
111  free(p);\
112 } while (0)
113 #else /* HAVE_BACKTRACE */
114 #define LOGTRACE(ctx,msg)
115 #endif /* HAVE_BACKTRACE */
116 
117 #define ERRSET(ctx,lvl,r,...) do {\
118  grn_ctx *ctx_ = (grn_ctx *)ctx;\
119  ctx_->errlvl = (lvl);\
120  ctx_->rc = (r);\
121  ctx_->errfile = __FILE__;\
122  ctx_->errline = __LINE__;\
123  ctx_->errfunc = __FUNCTION__;\
124  grn_ctx_impl_err(ctx);\
125  grn_ctx_log(ctx, __VA_ARGS__);\
126  if (grn_ctx_impl_should_log(ctx)) {\
127  grn_ctx_impl_set_current_error_message(ctx);\
128  GRN_LOG(ctx, lvl, __VA_ARGS__);\
129  BACKTRACE(ctx);\
130  if (lvl <= GRN_LOG_ERROR) { LOGTRACE(ctx, lvl); }\
131  }\
132 } while (0)
133 
134 #define ERRP(ctx,lvl) \
135  (((ctx) && ((grn_ctx *)(ctx))->errlvl <= (lvl)) || (grn_gctx.errlvl <= (lvl)))
136 
137 #define QLERR(...) do {\
138  ERRSET(ctx, GRN_WARN, GRN_INVALID_ARGUMENT, __VA_ARGS__);\
139  return F;\
140 } while (0)
141 
142 #define QLASSERT(expr) do {\
143  if (!(expr)) { QLERR("syntax error"); }\
144 } while (0)
145 
146 #ifdef ERR
147 # undef ERR
148 #endif /* ERR */
149 #define ERR(rc,...) ERRSET(ctx, GRN_ERROR, (rc), __VA_ARGS__)
150 #define WARN(rc,...) ERRSET(ctx, GRN_WARN, (rc), __VA_ARGS__)
151 #define MERR(...) ERRSET(ctx, GRN_ALERT, GRN_NO_MEMORY_AVAILABLE, __VA_ARGS__)
152 #define ALERT(...) ERRSET(ctx, GRN_ALERT, GRN_SUCCESS, __VA_ARGS__)
153 
154 #ifdef WIN32
155 #define SERR(str) do {\
156  grn_rc rc;\
157  const char *m;\
158  int e = WSAGetLastError();\
159  switch (e) {\
160  case WSANOTINITIALISED :\
161  rc = GRN_SOCKET_NOT_INITIALIZED;\
162  m = "please call grn_com_init first";\
163  break;\
164  case WSAEFAULT :\
165  rc = GRN_BAD_ADDRESS;\
166  m = "bad address";\
167  break;\
168  case WSAEINVAL :\
169  rc = GRN_INVALID_ARGUMENT;\
170  m = "invalid argument";\
171  break;\
172  case WSAEMFILE :\
173  rc = GRN_TOO_MANY_OPEN_FILES;\
174  m = "too many sockets";\
175  break;\
176  case WSAEWOULDBLOCK :\
177  rc = GRN_OPERATION_WOULD_BLOCK;\
178  m = "operation would block";\
179  break;\
180  case WSAENOTSOCK :\
181  rc = GRN_NOT_SOCKET;\
182  m = "given fd is not socket fd";\
183  break;\
184  case WSAEOPNOTSUPP :\
185  rc = GRN_OPERATION_NOT_SUPPORTED;\
186  m = "operation is not supported";\
187  break;\
188  case WSAEADDRINUSE :\
189  rc = GRN_ADDRESS_IS_IN_USE;\
190  m = "address is already in use";\
191  break;\
192  case WSAEADDRNOTAVAIL :\
193  rc = GRN_ADDRESS_IS_NOT_AVAILABLE;\
194  m = "address is not available";\
195  break;\
196  case WSAENETDOWN :\
197  rc = GRN_NETWORK_IS_DOWN;\
198  m = "network is down";\
199  break;\
200  case WSAENOBUFS :\
201  rc = GRN_NO_BUFFER;\
202  m = "no buffer";\
203  break;\
204  case WSAEISCONN :\
205  rc = GRN_SOCKET_IS_ALREADY_CONNECTED;\
206  m = "socket is already connected";\
207  break;\
208  case WSAENOTCONN :\
209  rc = GRN_SOCKET_IS_NOT_CONNECTED;\
210  m = "socket is not connected";\
211  break;\
212  case WSAESHUTDOWN :\
213  rc = GRN_SOCKET_IS_ALREADY_SHUTDOWNED;\
214  m = "socket is already shutdowned";\
215  break;\
216  case WSAETIMEDOUT :\
217  rc = GRN_OPERATION_TIMEOUT;\
218  m = "connection time out";\
219  break;\
220  case WSAECONNREFUSED :\
221  rc = GRN_CONNECTION_REFUSED;\
222  m = "connection refused";\
223  break;\
224  case WSAEINTR :\
225  rc = GRN_INTERRUPTED_FUNCTION_CALL;\
226  m = "interrupted function call";\
227  break;\
228  default:\
229  rc = GRN_UNKNOWN_ERROR;\
230  m = "unknown error";\
231  break;\
232  }\
233  ERR(rc, "syscall error '%s' (%s)", str, m);\
234 } while (0)
235 #else /* WIN32 */
236 #define SERR(str) do {\
237  grn_rc rc;\
238  switch (errno) {\
239  case ELOOP : rc = GRN_TOO_MANY_SYMBOLIC_LINKS; break;\
240  case ENAMETOOLONG : rc = GRN_FILENAME_TOO_LONG; break;\
241  case ENOENT : rc = GRN_NO_SUCH_FILE_OR_DIRECTORY; break;\
242  case ENOMEM : rc = GRN_NO_MEMORY_AVAILABLE; break;\
243  case ENOTDIR : rc = GRN_NOT_A_DIRECTORY; break;\
244  case EPERM : rc = GRN_OPERATION_NOT_PERMITTED; break;\
245  case ESRCH : rc = GRN_NO_SUCH_PROCESS; break;\
246  case EINTR : rc = GRN_INTERRUPTED_FUNCTION_CALL; break;\
247  case EIO : rc = GRN_INPUT_OUTPUT_ERROR; break;\
248  case ENXIO : rc = GRN_NO_SUCH_DEVICE_OR_ADDRESS; break;\
249  case E2BIG : rc = GRN_ARG_LIST_TOO_LONG; break;\
250  case ENOEXEC : rc = GRN_EXEC_FORMAT_ERROR; break;\
251  case EBADF : rc = GRN_BAD_FILE_DESCRIPTOR; break;\
252  case ECHILD : rc = GRN_NO_CHILD_PROCESSES; break;\
253  case EACCES : rc = GRN_PERMISSION_DENIED; break;\
254  case EFAULT : rc = GRN_BAD_ADDRESS; break;\
255  case EBUSY : rc = GRN_RESOURCE_BUSY; break;\
256  case EEXIST : rc = GRN_FILE_EXISTS; break;\
257  case ENODEV : rc = GRN_NO_SUCH_DEVICE; break;\
258  case EISDIR : rc = GRN_IS_A_DIRECTORY; break;\
259  case EINVAL : rc = GRN_INVALID_ARGUMENT; break;\
260  case EMFILE : rc = GRN_TOO_MANY_OPEN_FILES; break;\
261  case EFBIG : rc = GRN_FILE_TOO_LARGE; break;\
262  case ENOSPC : rc = GRN_NO_SPACE_LEFT_ON_DEVICE; break;\
263  case EROFS : rc = GRN_READ_ONLY_FILE_SYSTEM; break;\
264  case EMLINK : rc = GRN_TOO_MANY_LINKS; break;\
265  case EPIPE : rc = GRN_BROKEN_PIPE; break;\
266  case EDOM : rc = GRN_DOMAIN_ERROR; break;\
267  case ERANGE : rc = GRN_RANGE_ERROR; break;\
268  case ENOTSOCK : rc = GRN_NOT_SOCKET; break;\
269  case EADDRINUSE : rc = GRN_ADDRESS_IS_IN_USE; break;\
270  case ENETDOWN : rc = GRN_NETWORK_IS_DOWN; break;\
271  case ENOBUFS : rc = GRN_NO_BUFFER; break;\
272  case EISCONN : rc = GRN_SOCKET_IS_ALREADY_CONNECTED; break;\
273  case ENOTCONN : rc = GRN_SOCKET_IS_NOT_CONNECTED; break;\
274  /*\
275  case ESOCKTNOSUPPORT :\
276  case EOPNOTSUPP :\
277  case EPFNOSUPPORT :\
278  */\
279  case EPROTONOSUPPORT : rc = GRN_OPERATION_NOT_SUPPORTED; break;\
280  case ESHUTDOWN : rc = GRN_SOCKET_IS_ALREADY_SHUTDOWNED; break;\
281  case ETIMEDOUT : rc = GRN_OPERATION_TIMEOUT; break;\
282  case ECONNREFUSED: rc = GRN_CONNECTION_REFUSED; break;\
283  case EAGAIN: rc = GRN_OPERATION_WOULD_BLOCK; break;\
284  default : rc = GRN_UNKNOWN_ERROR; break;\
285  }\
286  ERR(rc, "syscall error '%s' (%s)", str, strerror(errno));\
287 } while (0)
288 #endif /* WIN32 */
290 #define GERR(rc,...) ERRSET(&grn_gctx, GRN_ERROR, (rc), __VA_ARGS__)
291 #define GMERR(...) ERRSET(&grn_gctx, GRN_ALERT, GRN_NO_MEMORY_AVAILABLE, __VA_ARGS__)
293 #define GRN_MALLOC(s) grn_malloc(ctx,s,__FILE__,__LINE__,__FUNCTION__)
294 #define GRN_CALLOC(s) grn_calloc(ctx,s,__FILE__,__LINE__,__FUNCTION__)
295 #define GRN_REALLOC(p,s) grn_realloc(ctx,p,s,__FILE__,__LINE__,__FUNCTION__)
296 #define GRN_STRDUP(s) grn_strdup(ctx,s,__FILE__,__LINE__,__FUNCTION__)
297 #define GRN_GMALLOC(s) grn_malloc(&grn_gctx,s,__FILE__,__LINE__,__FUNCTION__)
298 #define GRN_GCALLOC(s) grn_calloc(&grn_gctx,s,__FILE__,__LINE__,__FUNCTION__)
299 #define GRN_GREALLOC(p,s) grn_realloc(&grn_gctx,p,s,__FILE__,__LINE__,__FUNCTION__)
300 #define GRN_GSTRDUP(s) grn_strdup(&grn_gctx,s,__FILE__,__LINE__,__FUNCTION__)
301 #define GRN_FREE(p) grn_free(ctx,p,__FILE__,__LINE__,__FUNCTION__)
302 #define GRN_MALLOCN(t,n) ((t *)(GRN_MALLOC(sizeof(t) * (n))))
303 #define GRN_GFREE(p) grn_free(&grn_gctx,p,__FILE__,__LINE__,__FUNCTION__)
304 #define GRN_GMALLOCN(t,n) ((t *)(GRN_GMALLOC(sizeof(t) * (n))))
306 #ifdef DEBUG
307 #define GRN_ASSERT(s) grn_assert(ctx,(s),__FILE__,__LINE__,__FUNCTION__)
308 #else
309 #define GRN_ASSERT(s)
310 #endif
312 #define GRN_CTX_ALLOC(ctx,s) grn_ctx_calloc(ctx,s,__FILE__,__LINE__,__FUNCTION__)
313 #define GRN_CTX_FREE(ctx,p) grn_ctx_free(ctx,p,__FILE__,__LINE__,__FUNCTION__)
314 #define GRN_CTX_ALLOC_L(ctx,s) grn_ctx_alloc_lifo(ctx,s,f,__FILE__,__LINE__,__FUNCTION__)
315 #define GRN_CTX_FREE_L(ctx,p) grn_ctx_free_lifo(ctx,p,__FILE__,__LINE__,__FUNCTION__)
316 
317 void *grn_ctx_alloc(grn_ctx *ctx, size_t size, int flags,
318  const char* file, int line, const char *func);
319 void *grn_ctx_malloc(grn_ctx *ctx, size_t size,
320  const char* file, int line, const char *func);
321 void *grn_ctx_calloc(grn_ctx *ctx, size_t size,
322  const char* file, int line, const char *func);
323 void *grn_ctx_realloc(grn_ctx *ctx, void *ptr, size_t size,
324  const char* file, int line, const char *func);
325 char *grn_ctx_strdup(grn_ctx *ctx, const char *s,
326  const char* file, int line, const char *func);
327 void grn_ctx_free(grn_ctx *ctx, void *ptr,
328  const char* file, int line, const char *func);
329 void *grn_ctx_alloc_lifo(grn_ctx *ctx, size_t size,
330  const char* file, int line, const char *func);
331 void grn_ctx_free_lifo(grn_ctx *ctx, void *ptr,
332  const char* file, int line, const char *func);
333 
334 #ifdef USE_DYNAMIC_MALLOC_CHANGE
335 typedef void *(*grn_malloc_func) (grn_ctx *ctx, size_t size,
336  const char *file, int line, const char *func);
337 typedef void *(*grn_calloc_func) (grn_ctx *ctx, size_t size,
338  const char *file, int line, const char *func);
339 typedef void *(*grn_realloc_func) (grn_ctx *ctx, void *ptr, size_t size,
340  const char *file, int line, const char *func);
341 typedef char *(*grn_strdup_func) (grn_ctx *ctx, const char *string,
342  const char *file, int line, const char *func);
343 grn_malloc_func grn_ctx_get_malloc(grn_ctx *ctx);
344 void grn_ctx_set_malloc(grn_ctx *ctx, grn_malloc_func malloc_func);
345 grn_calloc_func grn_ctx_get_calloc(grn_ctx *ctx);
346 void grn_ctx_set_calloc(grn_ctx *ctx, grn_calloc_func calloc_func);
347 grn_realloc_func grn_ctx_get_realloc(grn_ctx *ctx);
348 void grn_ctx_set_realloc(grn_ctx *ctx, grn_realloc_func realloc_func);
349 grn_strdup_func grn_ctx_get_strdup(grn_ctx *ctx);
350 void grn_ctx_set_strdup(grn_ctx *ctx, grn_strdup_func strdup_func);
351 
352 void *grn_malloc(grn_ctx *ctx, size_t size, const char* file, int line, const char *func);
353 void *grn_calloc(grn_ctx *ctx, size_t size, const char* file, int line, const char *func);
354 void *grn_realloc(grn_ctx *ctx, void *ptr, size_t size, const char* file, int line, const char *func);
355 char *grn_strdup(grn_ctx *ctx, const char *s, const char* file, int line, const char *func);
356 #else
357 # define grn_malloc grn_malloc_default
358 # define grn_calloc grn_calloc_default
359 # define grn_realloc grn_realloc_default
360 # define grn_strdup grn_strdup_default
361 # define grn_free grn_free_default
362 #endif
363 
364 GRN_API void *grn_malloc_default(grn_ctx *ctx, size_t size, const char* file, int line, const char *func);
365 void *grn_calloc_default(grn_ctx *ctx, size_t size, const char* file, int line, const char *func);
366 void *grn_realloc_default(grn_ctx *ctx, void *ptr, size_t size, const char* file, int line, const char *func);
367 GRN_API char *grn_strdup_default(grn_ctx *ctx, const char *s, const char* file, int line, const char *func);
368 GRN_API void grn_free_default(grn_ctx *ctx, void *ptr, const char* file, int line, const char *func);
369 
370 #ifdef USE_FAIL_MALLOC
371 int grn_fail_malloc_check(size_t size, const char *file, int line, const char *func);
372 void *grn_malloc_fail(grn_ctx *ctx, size_t size, const char* file, int line, const char *func);
373 void *grn_calloc_fail(grn_ctx *ctx, size_t size, const char* file, int line, const char *func);
374 void *grn_realloc_fail(grn_ctx *ctx, void *ptr, size_t size, const char* file, int line, const char *func);
375 char *grn_strdup_fail(grn_ctx *ctx, const char *s, const char* file, int line, const char *func);
376 #endif
377 
378 void grn_assert(grn_ctx *ctx, int cond, const char* file, int line, const char* func);
379 
380 /**** grn_ctx ****/
381 
383 extern int grn_pagesize;
384 extern grn_critical_section grn_glock;
385 extern uint32_t grn_gtick;
387 #define GRN_CTX_ALLOCATED (0x80)
388 #define GRN_CTX_TEMPORARY_DISABLE_II_RESOLVE_SEL_AND (0x40)
389 
390 typedef struct {
391  int64_t tv_sec;
392  int32_t tv_nsec;
393 } grn_timeval;
396 
397 #ifndef GRN_TIMEVAL_STR_SIZE
398 #define GRN_TIMEVAL_STR_SIZE 0x100
399 #endif /* GRN_TIMEVAL_STR_SIZE */
400 #ifndef GRN_TIMEVAL_STR_FORMAT
401 #define GRN_TIMEVAL_STR_FORMAT "%04d-%02d-%02d %02d:%02d:%02d.%06d"
402 #endif /* GRN_TIMEVAL_STR_FORMAT */
403 #define GRN_TIME_NSEC_PER_SEC 1000000000
404 #define GRN_TIME_NSEC_PER_SEC_F 1000000000.0
405 #define GRN_TIME_NSEC_PER_USEC (GRN_TIME_NSEC_PER_SEC / GRN_TIME_USEC_PER_SEC)
406 #define GRN_TIME_NSEC_TO_USEC(nsec) ((nsec) / GRN_TIME_NSEC_PER_USEC)
407 #define GRN_TIME_USEC_TO_NSEC(usec) ((usec) * GRN_TIME_NSEC_PER_USEC)
408 
410 GRN_API grn_rc grn_timeval2str(grn_ctx *ctx, grn_timeval *tv, char *buf);
411 grn_rc grn_str2timeval(const char *str, uint32_t str_len, grn_timeval *tv);
412 
413 GRN_API void grn_ctx_log(grn_ctx *ctx, const char *fmt, ...) GRN_ATTRIBUTE_PRINTF(2);
414 void grn_ctx_qe_fin(grn_ctx *ctx);
415 void grn_ctx_loader_clear(grn_ctx *ctx);
416 void grn_log_reopen(grn_ctx *ctx);
417 
418 GRN_API grn_rc grn_ctx_sendv(grn_ctx *ctx, int argc, char **argv, int flags);
419 GRN_API void grn_ctx_set_next_expr(grn_ctx *ctx, grn_obj *expr);
420 
421 int grn_alloc_count(void);
422 
424 
425 /**** db_obj ****/
427 /* flag values used for grn_obj.header.impl_flags */
428 
429 #define GRN_OBJ_ALLOCATED (0x01<<2) /* allocated by ctx */
430 #define GRN_OBJ_EXPRVALUE (0x01<<3) /* value allocated by grn_expr */
431 #define GRN_OBJ_EXPRCONST (0x01<<4) /* constant allocated by grn_expr */
433 typedef struct _grn_hook grn_hook;
434 
435 typedef struct {
437  grn_id range; /* table: type of subrecords, column: type of values */
438  /* -- compatible with grn_accessor -- */
439  grn_id id;
440  grn_obj *db;
441  grn_user_data user_data;
442  grn_proc_func *finalizer;
443  grn_hook *hooks[5];
444  void *source;
445  uint32_t source_size;
446  uint32_t max_n_subrecs;
447  uint8_t subrec_size;
448  uint8_t subrec_offset;
449  uint8_t record_unit;
450  uint8_t subrec_unit;
451  // grn_obj_flags flags;
452 } grn_db_obj;
453 
454 #define GRN_DB_OBJ_SET_TYPE(db_obj,obj_type) do {\
455  (db_obj)->obj.header.type = (obj_type);\
456  (db_obj)->obj.header.impl_flags = 0;\
457  (db_obj)->obj.header.flags = 0;\
458  (db_obj)->obj.id = GRN_ID_NIL;\
459  (db_obj)->obj.user_data.ptr = NULL;\
460  (db_obj)->obj.finalizer = NULL;\
461  (db_obj)->obj.hooks[0] = NULL;\
462  (db_obj)->obj.hooks[1] = NULL;\
463  (db_obj)->obj.hooks[2] = NULL;\
464  (db_obj)->obj.hooks[3] = NULL;\
465  (db_obj)->obj.hooks[4] = NULL;\
466  (db_obj)->obj.source = NULL;\
467  (db_obj)->obj.source_size = 0;\
468 } while (0)
470 /**** cache ****/
472 typedef struct {
473  uint32_t nentries;
474  uint32_t max_nentries;
475  uint32_t nfetches;
476  uint32_t nhits;
478 
479 void grn_cache_init(void);
481  const char *str, uint32_t str_size);
482 void grn_cache_unref(grn_ctx *ctx, grn_cache *cache,
483  const char *str, uint32_t str_size);
484 void grn_cache_update(grn_ctx *ctx, grn_cache *cache,
485  const char *str, uint32_t str_size, grn_obj *value);
486 void grn_cache_expire(grn_cache *cache, int32_t size);
487 void grn_cache_fin(void);
488 void grn_cache_get_statistics(grn_ctx *ctx, grn_cache *cache,
489  grn_cache_statistics *statistics);
490 
491 /**** receive handler ****/
492 
493 void grn_ctx_concat_func(grn_ctx *ctx, int flags, void *dummy);
494 GRN_API void grn_ctx_stream_out_func(grn_ctx *c, int flags, void *stream);
495 
497 
498 #ifdef __cplusplus
499 }
500 #endif
501 
502 #endif /* GRN_CTX_H */