null+****@clear*****
null+****@clear*****
2010年 7月 26日 (月) 22:50:41 JST
Daijiro MORI 2010-07-26 13:50:41 +0000 (Mon, 26 Jul 2010)
New Revision: 4f4565478e33021714572734d96b4d8a14950937
Log:
Expanded critical section in grn_ja_replace().
Modified files:
lib/store.c
Modified: lib/store.c (+43 -18)
===================================================================
--- lib/store.c 2010-07-26 07:57:11 +0000 (e61f5bc)
+++ lib/store.c 2010-07-26 13:50:41 +0000 (f5b6946)
@@ -407,9 +407,7 @@ grn_ja_free(grn_ctx *ctx, grn_ja *ja, grn_ja_einfo *einfo)
uint32_t n;
EHUGE_DEC(einfo, seg, element_size);
n = ((element_size + JA_SEGMENT_SIZE - 1) >> GRN_JA_W_SEGMENT);
- if (grn_io_lock(ctx, ja->io, 10000000)) { return ctx->rc; }
for (; n--; seg++) { SEGMENTS_OFF(ja, seg); }
- grn_io_unlock(ja->io);
return GRN_SUCCESS;
}
EINFO_DEC(einfo, seg, pos, element_size);
@@ -425,23 +423,19 @@ grn_ja_free(grn_ctx *ctx, grn_ja *ja, grn_ja_einfo *einfo)
if (!addr) { return GRN_NO_MEMORY_AVAILABLE; }
aligned_size = (element_size + sizeof(grn_id) - 1) & ~(sizeof(grn_id) - 1);
*(uint32_t *)(addr + pos - sizeof(grn_id)) = DELETED|aligned_size;
- if (grn_io_lock(ctx, ja->io, 10000000)) { return ctx->rc; }
SEGMENTS_AT(ja, seg) -= (aligned_size + sizeof(grn_id));
if (SEGMENTS_AT(ja, seg) == SEG_SEQ) {
/* reuse the segment */
SEGMENTS_AT(ja, seg) = 0;
}
- grn_io_unlock(ja->io);
GRN_IO_SEG_UNREF(ja->io, seg);
} else {
uint32_t lseg = 0, lseg_;
gseg = &ja->header->garbages[m - JA_W_EINFO];
- if (grn_io_lock(ctx, ja->io, 10000000)) { return ctx->rc; }
while ((lseg_ = *gseg)) {
if (lseg) { GRN_IO_SEG_UNREF(ja->io, lseg); }
GRN_IO_SEG_REF(ja->io, lseg_, ginfo);
if (!ginfo) {
- grn_io_unlock(ja->io);
return GRN_NO_MEMORY_AVAILABLE;
}
lseg = lseg_;
@@ -453,7 +447,6 @@ grn_ja_free(grn_ctx *ctx, grn_ja *ja, grn_ja_einfo *einfo)
while (SEGMENTS_AT(ja, i)) {
if (++i >= JA_N_DSEGMENTS) {
if (lseg) { GRN_IO_SEG_UNREF(ja->io, lseg); }
- grn_io_unlock(ja->io);
return GRN_NO_MEMORY_AVAILABLE;
}
}
@@ -464,7 +457,6 @@ grn_ja_free(grn_ctx *ctx, grn_ja *ja, grn_ja_einfo *einfo)
GRN_IO_SEG_REF(ja->io, lseg_, ginfo);
lseg = lseg_;
if (!ginfo) {
- grn_io_unlock(ja->io);
return GRN_NO_MEMORY_AVAILABLE;
}
ginfo->head = 0;
@@ -477,7 +469,6 @@ grn_ja_free(grn_ctx *ctx, grn_ja *ja, grn_ja_einfo *einfo)
if (++ginfo->head == JA_N_GARBAGES_IN_A_SEGMENT) { ginfo->head = 0; }
ginfo->nrecs++;
ja->header->ngarbages[m - JA_W_EINFO]++;
- grn_io_unlock(ja->io);
if (lseg) { GRN_IO_SEG_UNREF(ja->io, lseg); }
}
return GRN_SUCCESS;
@@ -491,30 +482,30 @@ grn_ja_replace(grn_ctx *ctx, grn_ja *ja, grn_id id, grn_ja_einfo *ei)
lseg = id >> JA_W_EINFO_IN_A_SEGMENT;
pos = id & JA_M_EINFO_IN_A_SEGMENT;
pseg = &ja->header->esegs[lseg];
+ if (grn_io_lock(ctx, ja->io, 10000000)) { return ctx->rc; }
if (*pseg == JA_ESEG_VOID) {
- if (grn_io_lock(ctx, ja->io, 10000000)) { return ctx->rc; }
if (*pseg == JA_ESEG_VOID) {
int i = 0;
while (SEGMENTS_AT(ja, i)) {
if (++i >= JA_N_DSEGMENTS) {
- grn_io_unlock(ja->io);
ERR(GRN_NOT_ENOUGH_SPACE, "grn_ja file (%s) is full", ja->io->path);
- return ctx->rc;
+ goto exit;
}
}
SEGMENTS_EINFO_ON(ja, i, lseg);
*pseg = i;
}
- grn_io_unlock(ja->io);
}
GRN_IO_SEG_REF(ja->io, *pseg, einfo);
- if (!einfo) { return GRN_NO_MEMORY_AVAILABLE; }
+ if (!einfo) { goto exit; }
eback = einfo[pos];
// smb_wmb();
GRN_SET_64BIT(&einfo[pos], *ei);
GRN_IO_SEG_UNREF(ja->io, *pseg);
grn_ja_free(ctx, ja, &eback);
- return GRN_SUCCESS;
+exit :
+ grn_io_unlock(ja->io);
+ return ctx->rc;
}
#define JA_N_GARBAGES_TH 10
@@ -1042,9 +1033,8 @@ grn_ja_defrag_seg(grn_ctx *ctx, grn_ja *ja, uint32_t seg)
}
if (*segusage != SEG_SEQ) {
GRN_LOG(ctx, GRN_LOG_ERROR, "dseges[%d] = %d after defrag", seg, *segusage);
- return GRN_FILE_CORRUPT;
}
- *segusage = 0;
+ // *segusage = 0;
GRN_IO_SEG_UNREF(ja->io, seg);
return GRN_SUCCESS;
}
@@ -1082,7 +1072,7 @@ grn_ja_check(grn_ctx *ctx, grn_ja *ja)
GRN_OUTPUT_CSTR("max_element_size");
GRN_OUTPUT_INT64(h->max_element_size);
GRN_OUTPUT_MAP_CLOSE();
- GRN_OUTPUT_ARRAY_OPEN("DETAIL", 8);
+ GRN_OUTPUT_ARRAY_OPEN("DETAIL", -1);
for (seg = 0; seg < JA_N_DSEGMENTS; seg++) {
int dseg = SEGMENTS_AT(ja, seg);
if (dseg) {
@@ -1093,6 +1083,41 @@ grn_ja_check(grn_ctx *ctx, grn_ja *ja)
GRN_OUTPUT_INT64((dseg & SEG_MASK)>>28);
GRN_OUTPUT_CSTR("seg value");
GRN_OUTPUT_INT64(dseg & ~SEG_MASK);
+ if ((dseg & SEG_MASK) == SEG_SEQ) {
+ byte *v = NULL, *ve;
+ uint32_t element_size, cum = 0, sum = dseg & ~SEG_MASK;
+ //GRN_OUTPUT_CSTR("seg seq");
+ //GRN_OUTPUT_ARRAY_OPEN("SEQ", -1);
+ GRN_IO_SEG_REF(ja->io, seg, v);
+ if (v) {
+ ve = v + JA_SEGMENT_SIZE;
+ while (v < ve && cum < sum) {
+ grn_id id = *((grn_id *)v);
+ // GRN_OUTPUT_MAP_OPEN("ENTRY", -1);
+ // GRN_OUTPUT_CSTR("id");
+ // GRN_OUTPUT_INT64(id);
+ if (id & DELETED) {
+ element_size = (id & ~DELETED);
+ } else {
+ element_size = grn_ja_size(ctx, ja, id);
+ element_size = (element_size + sizeof(grn_id) - 1) & ~(sizeof(grn_id) - 1);
+ cum += sizeof(uint32_t) + element_size;
+ }
+ // GRN_OUTPUT_CSTR("size");
+ // GRN_OUTPUT_INT64(element_size);
+ // GRN_OUTPUT_CSTR("cum");
+ // GRN_OUTPUT_INT64(cum);
+ v += sizeof(uint32_t) + element_size;
+ // GRN_OUTPUT_MAP_CLOSE();
+ }
+ GRN_IO_SEG_UNREF(ja->io, seg);
+ }
+ //GRN_OUTPUT_ARRAY_CLOSE();
+ if (cum != sum) {
+ GRN_OUTPUT_CSTR("cum gap");
+ GRN_OUTPUT_INT64(cum - sum);
+ }
+ }
GRN_OUTPUT_MAP_CLOSE();
}
}