Kouhei Sutou
null+****@clear*****
Thu Mar 6 15:51:55 JST 2014
Kouhei Sutou 2014-03-06 15:51:55 +0900 (Thu, 06 Mar 2014) New Revision: e0adb78cbf921167476b56ceaad6c242671c6a4e https://github.com/groonga/groonga/commit/e0adb78cbf921167476b56ceaad6c242671c6a4e Merged c074380: Merge pull request #156 from groonga/ja-backward-compatible Message: ja: keep backward compatible for Groonga 4.0.0 or older DB Modified files: lib/store.c Modified: lib/store.c (+117 -23) =================================================================== --- lib/store.c 2014-03-06 14:43:11 +0900 (2a1e356) +++ lib/store.c 2014-03-06 15:51:55 +0900 (5ea1a3b) @@ -203,7 +203,8 @@ grn_ra_cache_fin(grn_ctx *ctx, grn_ra *ra, grn_id id) /**** jagged arrays ****/ -#define GRN_JA_W_SEGREGATE_THRESH 16 +#define GRN_JA_W_SEGREGATE_THRESH_V1 7 +#define GRN_JA_W_SEGREGATE_THRESH_V2 16 #define GRN_JA_W_CAPACITY 38 #define GRN_JA_W_SEGMENT 22 @@ -215,7 +216,8 @@ grn_ra_cache_fin(grn_ctx *ctx, grn_ra *ra, grn_id id) #define JA_N_EINFO_IN_A_SEGMENT (1U << JA_W_EINFO_IN_A_SEGMENT) #define JA_M_EINFO_IN_A_SEGMENT (JA_N_EINFO_IN_A_SEGMENT - 1) #define JA_N_GARBAGES_IN_A_SEGMENT ((1U << (GRN_JA_W_SEGMENT - 3)) - 2) -#define JA_N_ELEMENT_VARIATION (GRN_JA_W_SEGREGATE_THRESH - JA_W_EINFO + 1) +#define JA_N_ELEMENT_VARIATION_V1 (GRN_JA_W_SEGREGATE_THRESH_V1 - JA_W_EINFO + 1) +#define JA_N_ELEMENT_VARIATION_V2 (GRN_JA_W_SEGREGATE_THRESH_V2 - JA_W_EINFO + 1) #define JA_N_DSEGMENTS (1U << JA_W_SEGMENTS_MAX) #define JA_N_ESEGMENTS (1U << (GRN_ID_WIDTH - JA_W_EINFO_IN_A_SEGMENT)) @@ -282,16 +284,44 @@ typedef struct { ja_pos recs[JA_N_GARBAGES_IN_A_SEGMENT]; } grn_ja_ginfo; -struct grn_ja_header { +struct grn_ja_header_v1 { + uint32_t flags; + uint32_t curr_seg; + uint32_t curr_pos; + uint32_t max_element_size; + ja_pos free_elements[JA_N_ELEMENT_VARIATION_V1]; + uint32_t garbages[JA_N_ELEMENT_VARIATION_V1]; + uint32_t ngarbages[JA_N_ELEMENT_VARIATION_V1]; + uint32_t dsegs[JA_N_DSEGMENTS]; + uint32_t esegs[JA_N_ESEGMENTS]; +}; + +struct grn_ja_header_v2 { uint32_t flags; uint32_t curr_seg; uint32_t curr_pos; uint32_t max_element_size; - ja_pos free_elements[JA_N_ELEMENT_VARIATION]; - uint32_t garbages[JA_N_ELEMENT_VARIATION]; - uint32_t ngarbages[JA_N_ELEMENT_VARIATION]; + ja_pos free_elements[JA_N_ELEMENT_VARIATION_V2]; + uint32_t garbages[JA_N_ELEMENT_VARIATION_V2]; + uint32_t ngarbages[JA_N_ELEMENT_VARIATION_V2]; uint32_t dsegs[JA_N_DSEGMENTS]; uint32_t esegs[JA_N_ESEGMENTS]; + uint8_t segregate_threshold; + uint8_t n_element_variation; +}; + +struct grn_ja_header { + uint32_t flags; + uint32_t *curr_seg; + uint32_t *curr_pos; + uint32_t max_element_size; + ja_pos *free_elements; + uint32_t *garbages; + uint32_t *ngarbages; + uint32_t *dsegs; + uint32_t *esegs; + uint8_t segregate_threshold; + uint8_t n_element_variation; }; #define SEG_SEQ (0x10000000U) @@ -317,18 +347,41 @@ _grn_ja_create(grn_ctx *ctx, grn_ja *ja, const char *path, int i; grn_io *io; struct grn_ja_header *header; - io = grn_io_create(ctx, path, sizeof(struct grn_ja_header), + struct grn_ja_header_v2 *header_v2; + io = grn_io_create(ctx, path, sizeof(struct grn_ja_header_v2), JA_SEGMENT_SIZE, JA_N_DSEGMENTS, grn_io_auto, GRN_IO_EXPIRE_SEGMENT); if (!io) { return NULL; } grn_io_set_type(io, GRN_COLUMN_VAR_SIZE); - header = grn_io_header(io); - header->curr_pos = JA_SEGMENT_SIZE; - header->flags = flags; - for (i = 0; i < JA_N_ESEGMENTS; i++) { header->esegs[i] = JA_ESEG_VOID; } + + header_v2 = grn_io_header(io); + header_v2->flags = flags; + header_v2->curr_seg = 0; + header_v2->curr_pos = JA_SEGMENT_SIZE; + header_v2->max_element_size = max_element_size; + for (i = 0; i < JA_N_ESEGMENTS; i++) { header_v2->esegs[i] = JA_ESEG_VOID; } + header_v2->segregate_threshold = GRN_JA_W_SEGREGATE_THRESH_V2; + header_v2->n_element_variation = JA_N_ELEMENT_VARIATION_V2; + + header = GRN_GMALLOC(sizeof(struct grn_ja_header)); + if (!header) { + grn_io_close(ctx, io); + return NULL; + } + header->flags = header_v2->flags; + header->curr_seg = &(header_v2->curr_seg); + header->curr_pos = &(header_v2->curr_pos); + header->max_element_size = header_v2->max_element_size; + header->free_elements = header_v2->free_elements; + header->garbages = header_v2->garbages; + header->ngarbages = header_v2->ngarbages; + header->dsegs = header_v2->dsegs; + header->esegs = header_v2->esegs; + header->segregate_threshold = header_v2->segregate_threshold; + header->n_element_variation = header_v2->n_element_variation; + ja->io = io; ja->header = header; - header->max_element_size = max_element_size; SEGMENTS_EINFO_ON(ja, 0, 0); header->esegs[0] = 0; return ja; @@ -355,21 +408,56 @@ grn_ja_open(grn_ctx *ctx, const char *path) grn_io *io; grn_ja *ja = NULL; struct grn_ja_header *header; + struct grn_ja_header_v2 *header_v2; io = grn_io_open(ctx, path, grn_io_auto); if (!io) { return NULL; } - header = grn_io_header(io); + header_v2 = grn_io_header(io); if (grn_io_get_type(io) != GRN_COLUMN_VAR_SIZE) { ERR(GRN_INVALID_FORMAT, "file type unmatch"); grn_io_close(ctx, io); return NULL; } + if (header_v2->segregate_threshold == 0) { + header_v2->segregate_threshold = GRN_JA_W_SEGREGATE_THRESH_V1; + } + if (header_v2->n_element_variation == 0) { + header_v2->n_element_variation = JA_N_ELEMENT_VARIATION_V1; + } if (!(ja = GRN_GMALLOC(sizeof(grn_ja)))) { grn_io_close(ctx, io); return NULL; } GRN_DB_OBJ_SET_TYPE(ja, GRN_COLUMN_VAR_SIZE); + if (!(header = GRN_GMALLOC(sizeof(struct grn_ja_header)))) { + grn_io_close(ctx, io); + GRN_GFREE(ja); + return NULL; + } + + header->flags = header_v2->flags; + header->curr_seg = &(header_v2->curr_seg); + header->curr_pos = &(header_v2->curr_pos); + header->max_element_size = header_v2->max_element_size; + header->segregate_threshold = header_v2->segregate_threshold; + header->n_element_variation = header_v2->n_element_variation; + if (header->segregate_threshold == GRN_JA_W_SEGREGATE_THRESH_V1) { + struct grn_ja_header_v1 *header_v1 = (struct grn_ja_header_v1 *)header_v2; + header->free_elements = header_v1->free_elements; + header->garbages = header_v1->garbages; + header->ngarbages = header_v1->ngarbages; + header->dsegs = header_v1->dsegs; + header->esegs = header_v1->esegs; + } else { + header->free_elements = header_v2->free_elements; + header->garbages = header_v2->garbages; + header->ngarbages = header_v2->ngarbages; + header->dsegs = header_v2->dsegs; + header->esegs = header_v2->esegs; + } + ja->io = io; ja->header = header; + return ja; } @@ -387,6 +475,7 @@ grn_ja_close(grn_ctx *ctx, grn_ja *ja) grn_rc rc; if (!ja) { return GRN_INVALID_ARGUMENT; } rc = grn_io_close(ctx, ja->io); + GRN_GFREE(ja->header); GRN_GFREE(ja); return rc; } @@ -494,7 +583,7 @@ grn_ja_free(grn_ctx *ctx, grn_ja *ja, grn_ja_einfo *einfo) GRN_BIT_SCAN_REV(es, m); m++; } - if (m > GRN_JA_W_SEGREGATE_THRESH) { + if (m > ja->header->segregate_threshold) { byte *addr = NULL; GRN_IO_SEG_REF(ja->io, seg, addr); if (!addr) { return GRN_NO_MEMORY_AVAILABLE; } @@ -508,8 +597,8 @@ grn_ja_free(grn_ctx *ctx, grn_ja *ja, grn_ja_einfo *einfo) if (SEGMENTS_AT(ja, seg) == SEG_SEQ) { /* reuse the segment */ SEGMENTS_OFF(ja, seg); - if (seg == ja->header->curr_seg) { - ja->header->curr_pos = JA_SEGMENT_SIZE; + if (seg == *(ja->header->curr_seg)) { + *(ja->header->curr_pos) = JA_SEGMENT_SIZE; } } GRN_IO_SEG_UNREF(ja->io, seg); @@ -660,8 +749,9 @@ grn_ja_alloc(grn_ctx *ctx, grn_ja *ja, grn_id id, int m, aligned_size, es = element_size - 1; GRN_BIT_SCAN_REV(es, m); m++; - if (m > GRN_JA_W_SEGREGATE_THRESH) { - uint32_t seg = ja->header->curr_seg, pos = ja->header->curr_pos; + if (m > ja->header->segregate_threshold) { + uint32_t seg = *(ja->header->curr_seg); + uint32_t pos = *(ja->header->curr_pos); if (pos + element_size + sizeof(grn_id) > JA_SEGMENT_SIZE) { seg = 0; while (SEGMENTS_AT(ja, seg)) { @@ -672,7 +762,7 @@ grn_ja_alloc(grn_ctx *ctx, grn_ja *ja, grn_id id, } } SEGMENTS_SEQ_ON(ja, seg); - ja->header->curr_seg = seg; + *(ja->header->curr_seg) = seg; pos = 0; } GRN_IO_SEG_REF(ja->io, seg, addr); @@ -690,7 +780,7 @@ grn_ja_alloc(grn_ctx *ctx, grn_ja *ja, grn_id id, EINFO_ENC(einfo, seg, pos, element_size); iw->segment = seg; iw->addr = addr + pos; - ja->header->curr_pos = pos + aligned_size; + *(ja->header->curr_pos) = pos + aligned_size; grn_io_unlock(ja->io); return GRN_SUCCESS; } else { @@ -1350,7 +1440,7 @@ grn_ja_defrag(grn_ctx *ctx, grn_ja *ja, int threshold) int nsegs = 0; uint32_t seg, ts = 1U << (GRN_JA_W_SEGMENT - threshold); for (seg = 0; seg < JA_N_DSEGMENTS; seg++) { - if (seg == ja->header->curr_seg) { continue; } + if (seg == *(ja->header->curr_seg)) { continue; } if (((SEGMENTS_AT(ja, seg) & SEG_MASK) == SEG_SEQ) && ((SEGMENTS_AT(ja, seg) & ~SEG_MASK) < ts)) { if (!grn_ja_defrag_seg(ctx, ja, seg)) { nsegs++; } @@ -1371,11 +1461,15 @@ grn_ja_check(grn_ctx *ctx, grn_ja *ja) grn_itoh(h->flags, buf, 8); GRN_OUTPUT_STR(buf, 8); GRN_OUTPUT_CSTR("curr seg"); - GRN_OUTPUT_INT64(h->curr_seg); + GRN_OUTPUT_INT64(*(h->curr_seg)); GRN_OUTPUT_CSTR("curr pos"); - GRN_OUTPUT_INT64(h->curr_pos); + GRN_OUTPUT_INT64(*(h->curr_pos)); GRN_OUTPUT_CSTR("max_element_size"); GRN_OUTPUT_INT64(h->max_element_size); + GRN_OUTPUT_CSTR("segregate_threshold"); + GRN_OUTPUT_INT64(h->segregate_threshold); + GRN_OUTPUT_CSTR("n_element_variation"); + GRN_OUTPUT_INT64(h->n_element_variation); GRN_OUTPUT_MAP_CLOSE(); GRN_OUTPUT_ARRAY_OPEN("DETAIL", -1); for (seg = 0; seg < JA_N_DSEGMENTS; seg++) { -------------- next part -------------- HTML����������������������������...Download