Skip to content

Commit

Permalink
Merge pull request #543 from groonga/support-dirty-crash-detection
Browse files Browse the repository at this point in the history
Support detecting changed database isn't closed
  • Loading branch information
kou committed May 10, 2016
2 parents 8d94c7e + 7d44c23 commit e8958bc
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 2 deletions.
27 changes: 27 additions & 0 deletions lib/dat.cpp
Expand Up @@ -115,6 +115,7 @@ grn_dat_init(grn_ctx *, grn_dat *dat)
dat->normalizer = NULL;
GRN_PTR_INIT(&(dat->token_filters), GRN_OBJ_VECTOR, GRN_ID_NIL);
CRITICAL_SECTION_INIT(dat->lock);
dat->is_dirty = GRN_FALSE;
}

void
Expand All @@ -126,6 +127,10 @@ grn_dat_fin(grn_ctx *ctx, grn_dat *dat)
dat->old_trie = NULL;
dat->trie = NULL;
if (dat->io) {
if (dat->is_dirty) {
uint32_t n_dirty_opens;
GRN_ATOMIC_ADD_EX(&(dat->header->n_dirty_opens), -1, n_dirty_opens);
}
grn_io_close(ctx, dat->io);
dat->io = NULL;
}
Expand Down Expand Up @@ -1142,4 +1147,26 @@ grn_dat_flush(grn_ctx *ctx, grn_dat *dat)
return GRN_SUCCESS;
}

grn_rc
grn_dat_dirty(grn_ctx *ctx, grn_dat *dat)
{
if (!dat->io) {
return GRN_SUCCESS;
}

grn_rc rc = GRN_SUCCESS;

{
CriticalSection critical_section(&dat->lock);
if (!dat->is_dirty) {
uint32_t n_dirty_opens;
dat->is_dirty = GRN_TRUE;
GRN_ATOMIC_ADD_EX(&(dat->header->n_dirty_opens), 1, n_dirty_opens);
rc = grn_io_flush(ctx, dat->io);
}
}

return rc;
}

} // extern "C"
11 changes: 11 additions & 0 deletions lib/db.c
Expand Up @@ -664,7 +664,18 @@ grn_db_touch(grn_ctx *ctx, grn_obj *s)
static inline void
grn_obj_touch_db(grn_ctx *ctx, grn_obj *obj, grn_timeval *tv)
{
grn_db *db = (grn_db *)obj;

grn_obj_io(obj)->header->lastmod = tv->tv_sec;

switch (db->keys->header.type) {
case GRN_TABLE_PAT_KEY :
grn_pat_dirty(ctx, (grn_pat *)(db->keys));
break;
case GRN_TABLE_DAT_KEY :
grn_dat_dirty(ctx, (grn_dat *)(db->keys));
break;
}
}

void
Expand Down
6 changes: 5 additions & 1 deletion lib/grn_dat.h
Expand Up @@ -37,6 +37,7 @@ struct _grn_dat {
grn_obj *normalizer;
grn_obj token_filters;
grn_critical_section lock;
grn_bool is_dirty;
};

struct grn_dat_header {
Expand All @@ -45,7 +46,8 @@ struct grn_dat_header {
grn_id tokenizer;
uint32_t file_id;
grn_id normalizer;
uint32_t reserved[235];
uint32_t n_dirty_opens;
uint32_t reserved[234];
};

struct _grn_dat_cursor {
Expand Down Expand Up @@ -79,6 +81,8 @@ GRN_API grn_rc grn_dat_repair(grn_ctx *ctx, grn_dat *dat);

GRN_API grn_rc grn_dat_flush(grn_ctx *ctx, grn_dat *dat);

grn_rc grn_dat_dirty(grn_ctx *ctx, grn_dat *dat);

#ifdef __cplusplus
}
#endif
7 changes: 6 additions & 1 deletion lib/grn_pat.h
Expand Up @@ -41,6 +41,8 @@ struct _grn_pat {
grn_obj token_filters;
grn_id *cache;
uint32_t cache_size;
grn_bool is_dirty;
grn_critical_section lock;
};

#define GRN_PAT_NDELINFOS 0x100
Expand Down Expand Up @@ -68,7 +70,8 @@ struct grn_pat_header {
uint32_t n_garbages;
grn_id normalizer;
uint32_t truncated;
uint32_t reserved[1003];
uint32_t n_dirty_opens;
uint32_t reserved[1002];
grn_pat_delinfo delinfos[GRN_PAT_NDELINFOS];
grn_id garbages[GRN_PAT_MAX_KEY_SIZE + 1];
};
Expand Down Expand Up @@ -116,6 +119,8 @@ uint32_t grn_pat_total_key_size(grn_ctx *ctx, grn_pat *pat);

grn_bool grn_pat_is_key_encoded(grn_ctx *ctx, grn_pat *pat);

grn_rc grn_pat_dirty(grn_ctx *ctx, grn_pat *pat);

#ifdef __cplusplus
}
#endif
30 changes: 30 additions & 0 deletions lib/pat.c
Expand Up @@ -541,6 +541,8 @@ grn_pat_create(grn_ctx *ctx, const char *path, uint32_t key_size,
}
pat->cache = NULL;
pat->cache_size = 0;
pat->is_dirty = GRN_FALSE;
CRITICAL_SECTION_INIT(pat->lock);
return pat;
}

Expand Down Expand Up @@ -623,6 +625,8 @@ grn_pat_open(grn_ctx *ctx, const char *path)
}
pat->cache = NULL;
pat->cache_size = 0;
pat->is_dirty = GRN_FALSE;
CRITICAL_SECTION_INIT(pat->lock);
return pat;
}

Expand All @@ -649,13 +653,22 @@ grn_rc
grn_pat_close(grn_ctx *ctx, grn_pat *pat)
{
grn_rc rc;

CRITICAL_SECTION_FIN(pat->lock);

if (pat->is_dirty) {
uint32_t n_dirty_opens;
GRN_ATOMIC_ADD_EX(&(pat->header->n_dirty_opens), -1, n_dirty_opens);
}

if ((rc = grn_io_close(ctx, pat->io))) {
ERR(rc, "grn_io_close failed");
} else {
grn_pvector_fin(ctx, &pat->token_filters);
if (pat->cache) { grn_pat_cache_disable(ctx, pat); }
GRN_FREE(pat);
}

return rc;
}

Expand Down Expand Up @@ -3544,3 +3557,20 @@ grn_pat_is_key_encoded(grn_ctx *ctx, grn_pat *pat)

return KEY_NEEDS_CONVERT(pat, key_size);
}

grn_rc
grn_pat_dirty(grn_ctx *ctx, grn_pat *pat)
{
grn_rc rc = GRN_SUCCESS;

CRITICAL_SECTION_ENTER(pat->lock);
if (!pat->is_dirty) {
uint32_t n_dirty_opens;
pat->is_dirty = GRN_TRUE;
GRN_ATOMIC_ADD_EX(&(pat->header->n_dirty_opens), 1, n_dirty_opens);
rc = grn_io_flush(ctx, pat->io);
}
CRITICAL_SECTION_LEAVE(pat->lock);

return rc;
}

0 comments on commit e8958bc

Please sign in to comment.