1 | /* -*- c-basic-offset: 2 -*- */ |
2 | /* |
3 | Copyright(C) 2015-2017 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 "grn.h" |
20 | #include "grn_index_column.h" |
21 | #include "grn_pat.h" |
22 | #include "grn_dat.h" |
23 | #include "grn_ii.h" |
24 | |
25 | grn_bool |
26 | grn_obj_is_true(grn_ctx *ctx, grn_obj *obj) |
27 | { |
28 | if (!obj) { |
29 | return GRN_FALSE; |
30 | } |
31 | |
32 | switch (obj->header.type) { |
33 | case GRN_BULK : |
34 | switch (obj->header.domain) { |
35 | case GRN_DB_BOOL : |
36 | return GRN_BOOL_VALUE(obj); |
37 | break; |
38 | case GRN_DB_INT32 : |
39 | return GRN_INT32_VALUE(obj) != 0; |
40 | break; |
41 | case GRN_DB_UINT32 : |
42 | return GRN_UINT32_VALUE(obj) != 0; |
43 | break; |
44 | case GRN_DB_FLOAT : { |
45 | double float_value; |
46 | float_value = GRN_FLOAT_VALUE(obj); |
47 | return (float_value < -DBL_EPSILON || |
48 | DBL_EPSILON < float_value); |
49 | break; |
50 | } |
51 | case GRN_DB_SHORT_TEXT : |
52 | case GRN_DB_TEXT : |
53 | case GRN_DB_LONG_TEXT : |
54 | return GRN_TEXT_LEN(obj) != 0; |
55 | break; |
56 | default : |
57 | return GRN_FALSE; |
58 | break; |
59 | } |
60 | break; |
61 | case GRN_VECTOR : |
62 | return GRN_TRUE; |
63 | break; |
64 | default : |
65 | return GRN_FALSE; |
66 | break; |
67 | } |
68 | } |
69 | |
70 | grn_bool |
71 | grn_obj_is_builtin(grn_ctx *ctx, grn_obj *obj) |
72 | { |
73 | grn_id id; |
74 | |
75 | if (!obj) { return GRN_FALSE; } |
76 | |
77 | id = grn_obj_id(ctx, obj); |
78 | return grn_id_is_builtin(ctx, id); |
79 | } |
80 | |
81 | grn_bool |
82 | grn_obj_is_bulk(grn_ctx *ctx, grn_obj *obj) |
83 | { |
84 | if (!obj) { |
85 | return GRN_FALSE; |
86 | } |
87 | |
88 | return obj->header.type == GRN_BULK; |
89 | } |
90 | |
91 | grn_bool |
92 | grn_obj_is_text_family_bulk(grn_ctx *ctx, grn_obj *obj) |
93 | { |
94 | if (!grn_obj_is_bulk(ctx, obj)) { |
95 | return GRN_FALSE; |
96 | } |
97 | |
98 | return GRN_TYPE_IS_TEXT_FAMILY(obj->header.domain); |
99 | } |
100 | |
101 | grn_bool |
102 | grn_obj_is_table(grn_ctx *ctx, grn_obj *obj) |
103 | { |
104 | grn_bool is_table = GRN_FALSE; |
105 | |
106 | if (!obj) { |
107 | return GRN_FALSE; |
108 | } |
109 | |
110 | switch (obj->header.type) { |
111 | case GRN_TABLE_NO_KEY : |
112 | case GRN_TABLE_HASH_KEY : |
113 | case GRN_TABLE_PAT_KEY : |
114 | case GRN_TABLE_DAT_KEY : |
115 | is_table = GRN_TRUE; |
116 | default : |
117 | break; |
118 | } |
119 | |
120 | return is_table; |
121 | } |
122 | |
123 | grn_bool |
124 | grn_obj_is_column(grn_ctx *ctx, grn_obj *obj) |
125 | { |
126 | grn_bool is_column = GRN_FALSE; |
127 | |
128 | if (!obj) { |
129 | return GRN_FALSE; |
130 | } |
131 | |
132 | switch (obj->header.type) { |
133 | case GRN_COLUMN_FIX_SIZE : |
134 | case GRN_COLUMN_VAR_SIZE : |
135 | case GRN_COLUMN_INDEX : |
136 | is_column = GRN_TRUE; |
137 | default : |
138 | break; |
139 | } |
140 | |
141 | return is_column; |
142 | } |
143 | |
144 | grn_bool |
145 | grn_obj_is_scalar_column(grn_ctx *ctx, grn_obj *obj) |
146 | { |
147 | if (!grn_obj_is_column(ctx, obj)) { |
148 | return GRN_FALSE; |
149 | } |
150 | |
151 | return (obj->header.flags & GRN_OBJ_COLUMN_TYPE_MASK) == GRN_OBJ_COLUMN_SCALAR; |
152 | } |
153 | |
154 | grn_bool |
155 | grn_obj_is_vector_column(grn_ctx *ctx, grn_obj *obj) |
156 | { |
157 | if (!grn_obj_is_column(ctx, obj)) { |
158 | return GRN_FALSE; |
159 | } |
160 | |
161 | return ((obj->header.type == GRN_COLUMN_VAR_SIZE) && |
162 | ((obj->header.flags & GRN_OBJ_COLUMN_TYPE_MASK) == |
163 | GRN_OBJ_COLUMN_VECTOR)); |
164 | } |
165 | |
166 | grn_bool |
167 | grn_obj_is_weight_vector_column(grn_ctx *ctx, grn_obj *obj) |
168 | { |
169 | if (!grn_obj_is_vector_column(ctx, obj)) { |
170 | return GRN_FALSE; |
171 | } |
172 | |
173 | return (obj->header.flags & GRN_OBJ_WITH_WEIGHT) == GRN_OBJ_WITH_WEIGHT; |
174 | } |
175 | |
176 | grn_bool |
177 | grn_obj_is_reference_column(grn_ctx *ctx, grn_obj *obj) |
178 | { |
179 | grn_obj *range; |
180 | |
181 | if (!grn_obj_is_column(ctx, obj)) { |
182 | return GRN_FALSE; |
183 | } |
184 | |
185 | range = grn_ctx_at(ctx, grn_obj_get_range(ctx, obj)); |
186 | if (!range) { |
187 | return GRN_FALSE; |
188 | } |
189 | |
190 | switch (range->header.type) { |
191 | case GRN_TABLE_HASH_KEY: |
192 | case GRN_TABLE_PAT_KEY: |
193 | case GRN_TABLE_DAT_KEY: |
194 | case GRN_TABLE_NO_KEY: |
195 | return GRN_TRUE; |
196 | default: |
197 | return GRN_FALSE; |
198 | } |
199 | } |
200 | |
201 | grn_bool |
202 | grn_obj_is_data_column(grn_ctx *ctx, grn_obj *obj) |
203 | { |
204 | if (!grn_obj_is_column(ctx, obj)) { |
205 | return GRN_FALSE; |
206 | } |
207 | |
208 | return obj->header.type == GRN_COLUMN_FIX_SIZE || |
209 | obj->header.type == GRN_COLUMN_VAR_SIZE; |
210 | } |
211 | |
212 | grn_bool |
213 | grn_obj_is_index_column(grn_ctx *ctx, grn_obj *obj) |
214 | { |
215 | if (!grn_obj_is_column(ctx, obj)) { |
216 | return GRN_FALSE; |
217 | } |
218 | |
219 | return obj->header.type == GRN_COLUMN_INDEX; |
220 | } |
221 | |
222 | grn_bool |
223 | grn_obj_is_accessor(grn_ctx *ctx, grn_obj *obj) |
224 | { |
225 | if (!obj) { |
226 | return GRN_FALSE; |
227 | } |
228 | |
229 | return obj->header.type == GRN_ACCESSOR; |
230 | } |
231 | |
232 | grn_bool |
233 | grn_obj_is_key_accessor(grn_ctx *ctx, grn_obj *obj) |
234 | { |
235 | grn_accessor *accessor; |
236 | |
237 | if (!grn_obj_is_accessor(ctx, obj)) { |
238 | return GRN_FALSE; |
239 | } |
240 | |
241 | accessor = (grn_accessor *)obj; |
242 | if (accessor->next) { |
243 | return GRN_FALSE; |
244 | } |
245 | |
246 | return accessor->action == GRN_ACCESSOR_GET_KEY; |
247 | } |
248 | |
249 | grn_bool |
250 | grn_obj_is_type(grn_ctx *ctx, grn_obj *obj) |
251 | { |
252 | if (!obj) { |
253 | return GRN_FALSE; |
254 | } |
255 | |
256 | return obj->header.type == GRN_TYPE; |
257 | } |
258 | |
259 | grn_bool |
260 | grn_obj_is_text_family_type(grn_ctx *ctx, grn_obj *obj) |
261 | { |
262 | if (!grn_obj_is_type(ctx, obj)) { |
263 | return GRN_FALSE; |
264 | } |
265 | |
266 | return GRN_TYPE_IS_TEXT_FAMILY(grn_obj_id(ctx, obj)); |
267 | } |
268 | |
269 | grn_bool |
270 | grn_obj_is_proc(grn_ctx *ctx, grn_obj *obj) |
271 | { |
272 | if (!obj) { |
273 | return GRN_FALSE; |
274 | } |
275 | |
276 | return obj->header.type == GRN_PROC; |
277 | } |
278 | |
279 | grn_bool |
280 | grn_obj_is_tokenizer_proc(grn_ctx *ctx, grn_obj *obj) |
281 | { |
282 | grn_proc *proc; |
283 | |
284 | if (!grn_obj_is_proc(ctx, obj)) { |
285 | return GRN_FALSE; |
286 | } |
287 | |
288 | proc = (grn_proc *)obj; |
289 | return proc->type == GRN_PROC_TOKENIZER; |
290 | } |
291 | |
292 | grn_bool |
293 | grn_obj_is_function_proc(grn_ctx *ctx, grn_obj *obj) |
294 | { |
295 | grn_proc *proc; |
296 | |
297 | if (!grn_obj_is_proc(ctx, obj)) { |
298 | return GRN_FALSE; |
299 | } |
300 | |
301 | proc = (grn_proc *)obj; |
302 | return proc->type == GRN_PROC_FUNCTION; |
303 | } |
304 | |
305 | grn_bool |
306 | grn_obj_is_selector_proc(grn_ctx *ctx, grn_obj *obj) |
307 | { |
308 | grn_proc *proc; |
309 | |
310 | if (!grn_obj_is_function_proc(ctx, obj)) { |
311 | return GRN_FALSE; |
312 | } |
313 | |
314 | proc = (grn_proc *)obj; |
315 | return proc->callbacks.function.selector != NULL; |
316 | } |
317 | |
318 | grn_bool |
319 | grn_obj_is_selector_only_proc(grn_ctx *ctx, grn_obj *obj) |
320 | { |
321 | grn_proc *proc; |
322 | |
323 | if (!grn_obj_is_selector_proc(ctx, obj)) { |
324 | return GRN_FALSE; |
325 | } |
326 | |
327 | proc = (grn_proc *)obj; |
328 | return proc->funcs[PROC_INIT] == NULL; |
329 | } |
330 | |
331 | grn_bool |
332 | grn_obj_is_normalizer_proc(grn_ctx *ctx, grn_obj *obj) |
333 | { |
334 | grn_proc *proc; |
335 | |
336 | if (!grn_obj_is_proc(ctx, obj)) { |
337 | return GRN_FALSE; |
338 | } |
339 | |
340 | proc = (grn_proc *)obj; |
341 | return proc->type == GRN_PROC_NORMALIZER; |
342 | } |
343 | |
344 | grn_bool |
345 | grn_obj_is_token_filter_proc(grn_ctx *ctx, grn_obj *obj) |
346 | { |
347 | grn_proc *proc; |
348 | |
349 | if (!grn_obj_is_proc(ctx, obj)) { |
350 | return GRN_FALSE; |
351 | } |
352 | |
353 | proc = (grn_proc *)obj; |
354 | return proc->type == GRN_PROC_TOKEN_FILTER; |
355 | } |
356 | |
357 | grn_bool |
358 | grn_obj_is_scorer_proc(grn_ctx *ctx, grn_obj *obj) |
359 | { |
360 | grn_proc *proc; |
361 | |
362 | if (!grn_obj_is_proc(ctx, obj)) { |
363 | return GRN_FALSE; |
364 | } |
365 | |
366 | proc = (grn_proc *)obj; |
367 | return proc->type == GRN_PROC_SCORER; |
368 | } |
369 | |
370 | grn_bool |
371 | grn_obj_is_window_function_proc(grn_ctx *ctx, grn_obj *obj) |
372 | { |
373 | grn_proc *proc; |
374 | |
375 | if (!grn_obj_is_proc(ctx, obj)) { |
376 | return GRN_FALSE; |
377 | } |
378 | |
379 | proc = (grn_proc *)obj; |
380 | return proc->type == GRN_PROC_WINDOW_FUNCTION; |
381 | } |
382 | |
383 | grn_bool |
384 | grn_obj_is_expr(grn_ctx *ctx, grn_obj *obj) |
385 | { |
386 | if (!obj) { |
387 | return GRN_FALSE; |
388 | } |
389 | |
390 | return obj->header.type == GRN_EXPR; |
391 | } |
392 | |
393 | static void |
394 | grn_db_reindex(grn_ctx *ctx, grn_obj *db) |
395 | { |
396 | grn_table_cursor *cursor; |
397 | grn_id id; |
398 | |
399 | cursor = grn_table_cursor_open(ctx, db, |
400 | NULL, 0, NULL, 0, |
401 | 0, -1, |
402 | GRN_CURSOR_BY_ID); |
403 | if (!cursor) { |
404 | return; |
405 | } |
406 | |
407 | while ((id = grn_table_cursor_next(ctx, cursor)) != GRN_ID_NIL) { |
408 | grn_obj *object; |
409 | |
410 | object = grn_ctx_at(ctx, id); |
411 | if (!object) { |
412 | ERRCLR(ctx); |
413 | continue; |
414 | } |
415 | |
416 | switch (object->header.type) { |
417 | case GRN_TABLE_HASH_KEY : |
418 | case GRN_TABLE_PAT_KEY : |
419 | case GRN_TABLE_DAT_KEY : |
420 | grn_obj_reindex(ctx, object); |
421 | break; |
422 | default: |
423 | break; |
424 | } |
425 | |
426 | grn_obj_unlink(ctx, object); |
427 | |
428 | if (ctx->rc != GRN_SUCCESS) { |
429 | break; |
430 | } |
431 | } |
432 | grn_table_cursor_close(ctx, cursor); |
433 | } |
434 | |
435 | static void |
436 | grn_table_reindex(grn_ctx *ctx, grn_obj *table) |
437 | { |
438 | grn_hash *columns; |
439 | |
440 | columns = grn_hash_create(ctx, NULL, sizeof(grn_id), 0, |
441 | GRN_OBJ_TABLE_HASH_KEY | GRN_HASH_TINY); |
442 | if (!columns) { |
443 | ERR(GRN_NO_MEMORY_AVAILABLE, |
444 | "[table][reindex] failed to create a table to store columns" ); |
445 | return; |
446 | } |
447 | |
448 | if (grn_table_columns(ctx, table, "" , 0, (grn_obj *)columns) > 0) { |
449 | grn_id *key; |
450 | GRN_HASH_EACH(ctx, columns, id, &key, NULL, NULL, { |
451 | grn_obj *column = grn_ctx_at(ctx, *key); |
452 | if (column && column->header.type == GRN_COLUMN_INDEX) { |
453 | grn_obj_reindex(ctx, column); |
454 | } |
455 | }); |
456 | } |
457 | grn_hash_close(ctx, columns); |
458 | } |
459 | |
460 | static void |
461 | grn_data_column_reindex(grn_ctx *ctx, grn_obj *data_column) |
462 | { |
463 | grn_hook *hooks; |
464 | |
465 | for (hooks = DB_OBJ(data_column)->hooks[GRN_HOOK_SET]; |
466 | hooks; |
467 | hooks = hooks->next) { |
468 | grn_obj_default_set_value_hook_data *data = (void *)GRN_NEXT_ADDR(hooks); |
469 | grn_obj *target = grn_ctx_at(ctx, data->target); |
470 | if (target->header.type != GRN_COLUMN_INDEX) { |
471 | continue; |
472 | } |
473 | grn_obj_reindex(ctx, target); |
474 | if (ctx->rc != GRN_SUCCESS) { |
475 | break; |
476 | } |
477 | } |
478 | } |
479 | |
480 | grn_rc |
481 | grn_obj_reindex(grn_ctx *ctx, grn_obj *obj) |
482 | { |
483 | GRN_API_ENTER; |
484 | |
485 | if (!obj) { |
486 | ERR(GRN_INVALID_ARGUMENT, "[object][reindex] object must not be NULL" ); |
487 | GRN_API_RETURN(ctx->rc); |
488 | } |
489 | |
490 | switch (obj->header.type) { |
491 | case GRN_DB : |
492 | grn_db_reindex(ctx, obj); |
493 | break; |
494 | case GRN_TABLE_HASH_KEY : |
495 | case GRN_TABLE_PAT_KEY : |
496 | case GRN_TABLE_DAT_KEY : |
497 | grn_table_reindex(ctx, obj); |
498 | break; |
499 | case GRN_COLUMN_FIX_SIZE : |
500 | case GRN_COLUMN_VAR_SIZE : |
501 | grn_data_column_reindex(ctx, obj); |
502 | break; |
503 | case GRN_COLUMN_INDEX : |
504 | grn_index_column_rebuild(ctx, obj); |
505 | break; |
506 | default : |
507 | { |
508 | grn_obj type_name; |
509 | GRN_TEXT_INIT(&type_name, 0); |
510 | grn_inspect_type(ctx, &type_name, obj->header.type); |
511 | ERR(GRN_INVALID_ARGUMENT, |
512 | "[object][reindex] object must be TABLE_HASH_KEY, " |
513 | "TABLE_PAT_KEY, TABLE_DAT_KEY or COLUMN_INDEX: <%.*s>" , |
514 | (int)GRN_TEXT_LEN(&type_name), |
515 | GRN_TEXT_VALUE(&type_name)); |
516 | GRN_OBJ_FIN(ctx, &type_name); |
517 | GRN_API_RETURN(ctx->rc); |
518 | } |
519 | break; |
520 | } |
521 | |
522 | GRN_API_RETURN(ctx->rc); |
523 | } |
524 | |
525 | const char * |
526 | grn_obj_type_to_string(uint8_t type) |
527 | { |
528 | switch (type) { |
529 | case GRN_VOID : |
530 | return "void" ; |
531 | case GRN_BULK : |
532 | return "bulk" ; |
533 | case GRN_PTR : |
534 | return "ptr" ; |
535 | case GRN_UVECTOR : |
536 | return "uvector" ; |
537 | case GRN_PVECTOR : |
538 | return "pvector" ; |
539 | case GRN_VECTOR : |
540 | return "vector" ; |
541 | case GRN_MSG : |
542 | return "msg" ; |
543 | case GRN_QUERY : |
544 | return "query" ; |
545 | case GRN_ACCESSOR : |
546 | return "accessor" ; |
547 | case GRN_SNIP : |
548 | return "snip" ; |
549 | case GRN_PATSNIP : |
550 | return "patsnip" ; |
551 | case GRN_STRING : |
552 | return "string" ; |
553 | case GRN_CURSOR_TABLE_HASH_KEY : |
554 | return "cursor:table:hash_key" ; |
555 | case GRN_CURSOR_TABLE_PAT_KEY : |
556 | return "cursor:table:pat_key" ; |
557 | case GRN_CURSOR_TABLE_DAT_KEY : |
558 | return "cursor:table:dat_key" ; |
559 | case GRN_CURSOR_TABLE_NO_KEY : |
560 | return "cursor:table:no_key" ; |
561 | case GRN_CURSOR_COLUMN_INDEX : |
562 | return "cursor:column:index" ; |
563 | case GRN_CURSOR_COLUMN_GEO_INDEX : |
564 | return "cursor:column:geo_index" ; |
565 | case GRN_CURSOR_CONFIG : |
566 | return "cursor:config" ; |
567 | case GRN_TYPE : |
568 | return "type" ; |
569 | case GRN_PROC : |
570 | return "proc" ; |
571 | case GRN_EXPR : |
572 | return "expr" ; |
573 | case GRN_TABLE_HASH_KEY : |
574 | return "table:hash_key" ; |
575 | case GRN_TABLE_PAT_KEY : |
576 | return "table:pat_key" ; |
577 | case GRN_TABLE_DAT_KEY : |
578 | return "table:dat_key" ; |
579 | case GRN_TABLE_NO_KEY : |
580 | return "table:no_key" ; |
581 | case GRN_DB : |
582 | return "db" ; |
583 | case GRN_COLUMN_FIX_SIZE : |
584 | return "column:fix_size" ; |
585 | case GRN_COLUMN_VAR_SIZE : |
586 | return "column:var_size" ; |
587 | case GRN_COLUMN_INDEX : |
588 | return "column:index" ; |
589 | default : |
590 | return "unknown" ; |
591 | } |
592 | } |
593 | |
594 | grn_bool |
595 | grn_obj_name_is_column(grn_ctx *ctx, const char *name, int name_len) |
596 | { |
597 | if (!name) { |
598 | return GRN_FALSE; |
599 | } |
600 | |
601 | if (name_len < 0) { |
602 | name_len = strlen(name); |
603 | } |
604 | |
605 | return memchr(name, GRN_DB_DELIMITER, name_len) != NULL; |
606 | } |
607 | |
608 | grn_io * |
609 | grn_obj_get_io(grn_ctx *ctx, grn_obj *obj) |
610 | { |
611 | grn_io *io = NULL; |
612 | |
613 | if (!obj) { |
614 | return NULL; |
615 | } |
616 | |
617 | if (obj->header.type == GRN_DB) { |
618 | obj = ((grn_db *)obj)->keys; |
619 | } |
620 | |
621 | switch (obj->header.type) { |
622 | case GRN_TABLE_PAT_KEY : |
623 | io = ((grn_pat *)obj)->io; |
624 | break; |
625 | case GRN_TABLE_DAT_KEY : |
626 | io = ((grn_dat *)obj)->io; |
627 | break; |
628 | case GRN_TABLE_HASH_KEY : |
629 | io = ((grn_hash *)obj)->io; |
630 | break; |
631 | case GRN_TABLE_NO_KEY : |
632 | io = ((grn_array *)obj)->io; |
633 | break; |
634 | case GRN_COLUMN_VAR_SIZE : |
635 | io = ((grn_ja *)obj)->io; |
636 | break; |
637 | case GRN_COLUMN_FIX_SIZE : |
638 | io = ((grn_ra *)obj)->io; |
639 | break; |
640 | case GRN_COLUMN_INDEX : |
641 | io = ((grn_ii *)obj)->seg; |
642 | break; |
643 | } |
644 | |
645 | return io; |
646 | } |
647 | |
648 | size_t |
649 | grn_obj_get_disk_usage(grn_ctx *ctx, grn_obj *obj) |
650 | { |
651 | size_t usage = 0; |
652 | |
653 | GRN_API_ENTER; |
654 | |
655 | if (!obj) { |
656 | ERR(GRN_INVALID_ARGUMENT, "[object][disk-usage] object must not be NULL" ); |
657 | GRN_API_RETURN(0); |
658 | } |
659 | |
660 | switch (obj->header.type) { |
661 | case GRN_DB : |
662 | { |
663 | grn_db *db = (grn_db *)obj; |
664 | usage = grn_obj_get_disk_usage(ctx, db->keys); |
665 | if (db->specs) { |
666 | usage += grn_obj_get_disk_usage(ctx, (grn_obj *)(db->specs)); |
667 | } |
668 | usage += grn_obj_get_disk_usage(ctx, (grn_obj *)(db->config)); |
669 | } |
670 | break; |
671 | case GRN_TABLE_DAT_KEY : |
672 | usage = grn_dat_get_disk_usage(ctx, (grn_dat *)obj); |
673 | break; |
674 | case GRN_COLUMN_INDEX : |
675 | usage = grn_ii_get_disk_usage(ctx, (grn_ii *)obj); |
676 | break; |
677 | default : |
678 | { |
679 | grn_io *io; |
680 | io = grn_obj_get_io(ctx, obj); |
681 | if (io) { |
682 | usage = grn_io_get_disk_usage(ctx, io); |
683 | } |
684 | } |
685 | break; |
686 | } |
687 | |
688 | GRN_API_RETURN(usage); |
689 | } |
690 | |