Susumu Yata
null+****@clear*****
Thu Dec 10 17:21:27 JST 2015
Susumu Yata 2015-12-10 17:21:27 +0900 (Thu, 10 Dec 2015) New Revision: 2c143c4c761294c371d1f759e325752895a12d5b https://github.com/groonga/groonga/commit/2c143c4c761294c371d1f759e325752895a12d5b Message: grn_ja_reader: add grn_ja_reader_ref/unref() GitHub; #446 Modified files: lib/grn_store.h lib/store.c Modified: lib/grn_store.h (+29 -12) =================================================================== --- lib/grn_store.h 2015-12-10 12:35:01 +0900 (1c92a85) +++ lib/grn_store.h 2015-12-10 17:21:27 +0900 (b1580c7) @@ -102,22 +102,30 @@ GRN_API uint32_t grn_ja_size(grn_ctx *ctx, grn_ja *ja, grn_id id); void grn_ja_check(grn_ctx *ctx, grn_ja *ja); +#define GRN_JA_READER_INITIAL_REF_SEG_IDS_SIZE 16 + /* * grn_ja_reader is designed to improve the performance of sequential access. */ typedef struct { - grn_ja *ja; /* Target jagged array (without ref. count). */ - uint32_t einfo_seg_id; /* ID of the current header segment. */ - void *einfo_seg_addr; /* Address of the current header segment. */ - void *einfo; /* Header of the current value. */ - uint32_t body_seg_id; /* ID of the current body segment. */ - uint32_t body_seg_offset; /* Offset in the current body segment. */ - void *body_seg_addr; /* Address of the current body segment. */ - uint32_t value_size; /* Size of the current value. */ - uint32_t packed_size; /* Compressed size of the current value. */ - void *packed_buf; /* Buffer for decompression. */ - uint32_t packed_buf_size; /* Size of the buffer for decompression. */ - void *stream; /* Stream of a compression library. */ + grn_ja *ja; /* Target jagged array (without ref. count). */ + uint32_t einfo_seg_id; /* ID of the current header segment. */ + void *einfo_seg_addr; /* Address of the current header segment. */ + void *einfo; /* Header of the current value. */ + grn_bool ref_avail; /* grn_ja_reader_ref() is available or not. */ + uint32_t ref_seg_id; /* ID of the current referenced segment. */ + void *ref_seg_addr; /* Address of the current referenced segment. */ + uint32_t *ref_seg_ids; /* IDs of referenced segments. */ + uint32_t nref_seg_ids; /* Number of referenced segments. */ + uint32_t ref_seg_ids_size; /* Maximum number of referenced segments. */ + uint32_t body_seg_id; /* ID of the current body segment. */ + uint32_t body_seg_offset; /* Offset in the current body segment. */ + void *body_seg_addr; /* Address of the current body segment. */ + uint32_t value_size; /* Size of the current value. */ + uint32_t packed_size; /* Compressed size of the current value. */ + void *packed_buf; /* Buffer for decompression. */ + uint32_t packed_buf_size; /* Size of the buffer for decompression. */ + void *stream; /* Stream of a compression library. */ } grn_ja_reader; /* @@ -144,6 +152,15 @@ grn_rc grn_ja_reader_close(grn_ctx *ctx, grn_ja_reader *reader); */ grn_rc grn_ja_reader_seek(grn_ctx *ctx, grn_ja_reader *reader, grn_id id); +/* + * grn_ja_reader_ref() gets the address to the current value. + * This function is available if `reader->ref_avail` is true. + */ +grn_rc grn_ja_reader_ref(grn_ctx *ctx, grn_ja_reader *reader, void **addr); + +/* grn_ja_reader_unref() frees refereces returned by grn_ja_reader_ref(). */ +grn_rc grn_ja_reader_unref(grn_ctx *ctx, grn_ja_reader *reader); + /* grn_ja_reader_read() reads the current value to `buf`. */ grn_rc grn_ja_reader_read(grn_ctx *ctx, grn_ja_reader *reader, void *buf); Modified: lib/store.c (+58 -0) =================================================================== --- lib/store.c 2015-12-10 12:35:01 +0900 (3050d20) +++ lib/store.c 2015-12-10 17:21:27 +0900 (0eac8da) @@ -1580,6 +1580,11 @@ grn_ja_reader_init(grn_ctx *ctx, grn_ja_reader *reader, grn_ja *ja) { reader->ja = ja; reader->einfo_seg_id = JA_ESEG_VOID; + reader->ref_avail = GRN_FALSE; + reader->ref_seg_id = JA_ESEG_VOID; + reader->ref_seg_ids = NULL; + reader->nref_seg_ids = 0; + reader->ref_seg_ids_size = 0; reader->body_seg_id = JA_ESEG_VOID; reader->body_seg_addr = NULL; reader->packed_buf = NULL; @@ -1610,6 +1615,10 @@ grn_ja_reader_fin(grn_ctx *ctx, grn_ja_reader *reader) if (reader->einfo_seg_id != JA_ESEG_VOID) { GRN_IO_SEG_UNREF(reader->ja->io, reader->einfo_seg_id); } + if (reader->ref_seg_ids) { + grn_ja_reader_unref(ctx, reader); + GRN_FREE(reader->ref_seg_ids); + } if (reader->body_seg_addr) { GRN_IO_SEG_UNREF(reader->ja->io, reader->body_seg_id); } @@ -1729,11 +1738,14 @@ grn_ja_reader_seek_raw(grn_ctx *ctx, grn_ja_reader *reader, grn_id id) reader->einfo = einfo; if (ETINY_P(einfo)) { ETINY_DEC(einfo, reader->value_size); + reader->ref_avail = GRN_FALSE; } else { if (EHUGE_P(einfo)) { EHUGE_DEC(einfo, seg_id, reader->value_size); + reader->ref_avail = GRN_FALSE; } else { EINFO_DEC(einfo, seg_id, reader->body_seg_offset, reader->value_size); + reader->ref_avail = GRN_TRUE; } if (reader->body_seg_addr) { if (seg_id != reader->body_seg_id) { @@ -1762,6 +1774,52 @@ grn_ja_reader_seek(grn_ctx *ctx, grn_ja_reader *reader, grn_id id) return grn_ja_reader_seek_raw(ctx, reader, id); } +grn_rc grn_ja_reader_ref(grn_ctx *ctx, grn_ja_reader *reader, void **addr) +{ + if (!reader->ref_avail) { + return GRN_INVALID_ARGUMENT; + } + if (reader->body_seg_id != reader->ref_seg_id) { + void *seg_addr; + if (reader->nref_seg_ids == reader->ref_seg_ids_size) { + size_t n_bytes; + uint32_t new_size, *new_seg_ids; + if (reader->ref_seg_ids_size == 0) { + new_size = GRN_JA_READER_INITIAL_REF_SEG_IDS_SIZE; + } else { + new_size = reader->ref_seg_ids_size * 2; + } + n_bytes = sizeof(uint32_t) * new_size; + new_seg_ids = (uint32_t *)GRN_REALLOC(reader->ref_seg_ids, n_bytes); + if (!new_seg_ids) { + return GRN_NO_MEMORY_AVAILABLE; + } + reader->ref_seg_ids = new_seg_ids; + reader->ref_seg_ids_size = new_size; + } + GRN_IO_SEG_REF(reader->ja->io, reader->body_seg_id, seg_addr); + if (!seg_addr) { + return GRN_UNKNOWN_ERROR; + } + reader->ref_seg_id = reader->body_seg_id; + reader->ref_seg_addr = seg_addr; + reader->ref_seg_ids[reader->nref_seg_ids++] = reader->body_seg_id; + } + *addr = (char *)reader->ref_seg_addr + reader->body_seg_offset; + return GRN_SUCCESS; +} + +grn_rc grn_ja_reader_unref(grn_ctx *ctx, grn_ja_reader *reader) +{ + uint32_t i; + for (i = 0; i < reader->nref_seg_ids; i++) { + GRN_IO_SEG_UNREF(reader->ja->io, reader->ref_seg_ids[i]); + } + reader->ref_seg_id = JA_ESEG_VOID; + reader->nref_seg_ids = 0; + return GRN_FUNCTION_NOT_IMPLEMENTED; +} + #ifdef GRN_WITH_ZLIB /* grn_ja_reader_read_zlib() reads a value compressed with zlib. */ static grn_rc -------------- next part -------------- HTML����������������������������... Download