[Groonga-commit] groonga/groonga [master] Added grn_table_truncate()

Back to archive index

null+****@clear***** null+****@clear*****
2011年 2月 8日 (火) 19:55:49 JST


Daijiro MORI	2011-02-08 10:55:49 +0000 (Tue, 08 Feb 2011)

  New Revision: 3e0774f3e14115988756728cbf026ae4ed8fb690

  Log:
    Added grn_table_truncate()

  Modified files:
    lib/db.c
    lib/ii.c
    lib/store.c

  Modified: lib/db.c (+65 -5)
===================================================================
--- lib/db.c    2011-02-02 07:20:45 +0000 (96b68fd)
+++ lib/db.c    2011-02-08 10:55:49 +0000 (489b77c)
@@ -1364,21 +1364,81 @@ grn_table_delete_by_id(grn_ctx *ctx, grn_obj *table, grn_id id)
   GRN_API_RETURN(rc);
 }
 
+grn_rc grn_ii_truncate(grn_ctx *ctx, grn_ii *ii);
+grn_rc grn_ja_truncate(grn_ctx *ctx, grn_ja *ja);
+grn_rc grn_ra_truncate(grn_ctx *ctx, grn_ra *ra);
+
 grn_rc
-grn_table_truncate(grn_ctx *ctx, grn_obj *table)
+grn_column_truncate(grn_ctx *ctx, grn_obj *column)
 {
   grn_rc rc = GRN_INVALID_ARGUMENT;
   GRN_API_ENTER;
+  if (column) {
+    grn_hook *hooks;
+    switch (column->header.type) {
+    case GRN_COLUMN_VAR_SIZE :
+      for (hooks = DB_OBJ(column)->hooks[GRN_HOOK_SET]; hooks; hooks = hooks->next) {
+        default_set_value_hook_data *data = (void *)NEXT_ADDR(hooks);
+        grn_obj *target = grn_ctx_at(ctx, data->target);
+        if (target->header.type != GRN_COLUMN_INDEX) { continue; }
+        if ((rc = grn_ii_truncate(ctx, (grn_ii *)target))) { goto exit; }
+      }
+      rc = grn_ja_truncate(ctx, (grn_ja *)column);
+      break;
+    case GRN_COLUMN_FIX_SIZE :
+      for (hooks = DB_OBJ(column)->hooks[GRN_HOOK_SET]; hooks; hooks = hooks->next) {
+        default_set_value_hook_data *data = (void *)NEXT_ADDR(hooks);
+        grn_obj *target = grn_ctx_at(ctx, data->target);
+        if (target->header.type != GRN_COLUMN_INDEX) { continue; }
+        if ((rc = grn_ii_truncate(ctx, (grn_ii *)target))) { goto exit; }
+      }
+      rc = grn_ra_truncate(ctx, (grn_ra *)column);
+      break;
+    }
+  }
+exit :
+  GRN_API_RETURN(rc);
+}
 
-  ERR(GRN_FUNCTION_NOT_IMPLEMENTED, "grn_table_truncate() is not implemented.");
-  rc = GRN_FUNCTION_NOT_IMPLEMENTED;
-#if 0
+grn_rc
+grn_table_truncate(grn_ctx *ctx, grn_obj *table)
+{
+  grn_rc rc = GRN_INVALID_ARGUMENT;
+  GRN_API_ENTER;
   if (table) {
+    grn_hook *hooks;
+    grn_obj cols, **p, **pe;
+    GRN_PTR_INIT(&cols, GRN_OBJ_VECTOR, GRN_ID_NIL);
+    if ((rc = grn_obj_columns(ctx, table, "", 0, &cols))) {
+      GRN_OBJ_FIN(ctx, &cols);
+      goto exit;
+    }
+    p = (grn_obj **)GRN_BULK_HEAD(&cols);
+    pe = (grn_obj **)GRN_BULK_CURR(&cols);
+    for (; p < pe; p++) {
+      if ((rc = grn_column_truncate(ctx, *p))) {
+        GRN_OBJ_FIN(ctx, &cols);
+        goto exit;
+      }
+    }
+    GRN_OBJ_FIN(ctx, &cols);
     switch (table->header.type) {
     case GRN_TABLE_PAT_KEY :
+      for (hooks = DB_OBJ(table)->hooks[GRN_HOOK_INSERT]; hooks; hooks = hooks->next) {
+        default_set_value_hook_data *data = (void *)NEXT_ADDR(hooks);
+        grn_obj *target = grn_ctx_at(ctx, data->target);
+        if (target->header.type != GRN_COLUMN_INDEX) { continue; }
+        if ((rc = grn_ii_truncate(ctx, (grn_ii *)target))) { goto exit; }
+      }
       rc = grn_pat_truncate(ctx, (grn_pat *)table);
       break;
     case GRN_TABLE_HASH_KEY :
+      for (hooks = DB_OBJ(table)->hooks[GRN_HOOK_INSERT]; hooks; hooks = hooks->next) {
+        default_set_value_hook_data *data = (void *)NEXT_ADDR(hooks);
+        grn_obj *target = grn_ctx_at(ctx, data->target);
+        if (target->header.type != GRN_COLUMN_INDEX) { continue; }
+        if ((rc = grn_ii_truncate(ctx, (grn_ii *)target))) { goto exit; }
+      }
       rc = grn_hash_truncate(ctx, (grn_hash *)table);
       break;
     case GRN_TABLE_NO_KEY :
@@ -1387,7 +1447,7 @@ grn_table_truncate(grn_ctx *ctx, grn_obj *table)
     }
     grn_obj_touch(ctx, table, NULL);
   }
-#endif
+exit :
   GRN_API_RETURN(rc);
 }
 

  Modified: lib/ii.c (+56 -8)
===================================================================
--- lib/ii.c    2011-02-02 07:20:45 +0000 (fc9013d)
+++ lib/ii.c    2011-02-08 10:55:49 +0000 (7fe6433)
@@ -3389,12 +3389,11 @@ buffer_new(grn_ctx *ctx, grn_ii *ii, int size, uint32_t *pos,
 
 /* ii */
 
-grn_ii *
-grn_ii_create(grn_ctx *ctx, const char *path, grn_obj *lexicon, uint32_t flags)
+static grn_ii *
+_grn_ii_create(grn_ctx *ctx, grn_ii *ii, const char *path, grn_obj *lexicon, uint32_t flags)
 {
   int i;
   grn_io *seg, *chunk;
-  grn_ii *ii;
   char path2[PATH_MAX];
   struct grn_ii_header *header;
   grn_obj_flags lflags;
@@ -3433,11 +3432,6 @@ grn_ii_create(grn_ctx *ctx, const char *path, grn_obj *lexicon, uint32_t flags)
     header->free_chunks[i] = NOT_ASSIGNED;
     header->garbages[i] = NOT_ASSIGNED;
   }
-  if (!(ii = GRN_GMALLOC(sizeof(grn_ii)))) {
-    grn_io_close(ctx, seg);
-    grn_io_close(ctx, chunk);
-    return NULL;
-  }
   header->flags = flags;
   GRN_DB_OBJ_SET_TYPE(ii, GRN_COLUMN_INDEX);
   ii->seg = seg;
@@ -3453,6 +3447,20 @@ grn_ii_create(grn_ctx *ctx, const char *path, grn_obj *lexicon, uint32_t flags)
   return ii;
 }
 
+grn_ii *
+grn_ii_create(grn_ctx *ctx, const char *path, grn_obj *lexicon, uint32_t flags)
+{
+  grn_ii *ii = NULL;
+  if (!(ii = GRN_GMALLOC(sizeof(grn_ii)))) {
+    return NULL;
+  }
+  if (!_grn_ii_create(ctx, ii, path, lexicon, flags)) {
+    GRN_FREE(ii);
+    return NULL;
+  }
+  return ii;
+}
+
 grn_rc
 grn_ii_remove(grn_ctx *ctx, const char *path)
 {
@@ -3466,6 +3474,46 @@ exit :
   return rc;
 }
 
+grn_rc
+grn_ii_truncate(grn_ctx *ctx, grn_ii *ii)
+{
+  grn_rc rc;
+  char *segpath, *chunkpath;
+  grn_obj *lexicon;
+  uint32_t flags;
+  if ((segpath = (char *)grn_io_path(ii->seg)) && *segpath != '\0') {
+    if (!(segpath = GRN_STRDUP(segpath))) {
+      ERR(GRN_NO_MEMORY_AVAILABLE, "cannot duplicate path.");
+      return GRN_NO_MEMORY_AVAILABLE;
+    }
+    if ((chunkpath = (char *)grn_io_path(ii->chunk)) && *chunkpath != '\0') {
+      if (!(chunkpath = GRN_STRDUP(chunkpath))) {
+        ERR(GRN_NO_MEMORY_AVAILABLE, "cannot duplicate path.");
+        return GRN_NO_MEMORY_AVAILABLE;
+      }
+    } else {
+      chunkpath = NULL;
+    }
+  } else {
+    segpath = NULL;
+  }
+  lexicon = ii->lexicon;
+  flags = ii->header->flags;
+  if ((rc = grn_io_close(ctx, ii->seg))) { goto exit; }
+  if ((rc = grn_io_close(ctx, ii->seg))) { goto exit; }
+  ii->seg = NULL;
+  ii->chunk = NULL;
+  if (segpath && (rc = grn_io_remove(ctx, segpath))) { goto exit; }
+  if (chunkpath && (rc = grn_io_remove(ctx, chunkpath))) { goto exit; }
+  if (!_grn_ii_create(ctx, ii, segpath, lexicon, flags)) {
+    rc = GRN_UNKNOWN_ERROR;
+  }
+exit:
+  if (segpath) { GRN_FREE(segpath); }
+  if (chunkpath) { GRN_FREE(chunkpath); }
+  return rc;
+}
+
 grn_ii *
 grn_ii_open(grn_ctx *ctx, const char *path, grn_obj *lexicon)
 {

  Modified: lib/store.c (+87 -14)
===================================================================
--- lib/store.c    2011-02-02 07:20:45 +0000 (07f3233)
+++ lib/store.c    2011-02-08 10:55:49 +0000 (5e3828d)
@@ -25,12 +25,11 @@
 
 #define GRN_RA_SEGMENT_SIZE (1 << 22)
 
-grn_ra *
-grn_ra_create(grn_ctx *ctx, const char *path, unsigned int element_size)
+static grn_ra *
+_grn_ra_create(grn_ctx *ctx, grn_ra *ra, const char *path, unsigned int element_size)
 {
   grn_io *io;
   int max_segments, n_elm, w_elm;
-  grn_ra *ra = NULL;
   struct grn_ra_header *header;
   unsigned actual_size;
   if (element_size > GRN_RA_SEGMENT_SIZE) {
@@ -46,10 +45,6 @@ grn_ra_create(grn_ctx *ctx, const char *path, unsigned int element_size)
   header = grn_io_header(io);
   grn_io_set_type(io, GRN_COLUMN_FIX_SIZE);
   header->element_size = actual_size;
-  if (!(ra = GRN_GMALLOC(sizeof(grn_ra)))) {
-    grn_io_close(ctx, io);
-    return NULL;
-  }
   n_elm = GRN_RA_SEGMENT_SIZE / header->element_size;
   for (w_elm = 22; (1 << w_elm) > n_elm; w_elm--);
   GRN_DB_OBJ_SET_TYPE(ra, GRN_COLUMN_FIX_SIZE);
@@ -61,6 +56,20 @@ grn_ra_create(grn_ctx *ctx, const char *path, unsigned int element_size)
 }
 
 grn_ra *
+grn_ra_create(grn_ctx *ctx, const char *path, unsigned int element_size)
+{
+  grn_ra *ra = NULL;
+  if (!(ra = GRN_GMALLOC(sizeof(grn_ra)))) {
+    return NULL;
+  }
+  if (!_grn_ra_create(ctx, ra, path, element_size)) {
+    GRN_FREE(ra);
+    return NULL;
+  }
+  return ra;
+}
+
+grn_ra *
 grn_ra_open(grn_ctx *ctx, const char *path)
 {
   grn_io *io;
@@ -114,6 +123,32 @@ grn_ra_remove(grn_ctx *ctx, const char *path)
   return grn_io_remove(ctx, path);
 }
 
+grn_rc
+grn_ra_truncate(grn_ctx *ctx, grn_ra *ra)
+{
+  grn_rc rc;
+  char *path;
+  unsigned int element_size;
+  if ((path = (char *)grn_io_path(ra->io)) && *path != '\0') {
+    if (!(path = GRN_STRDUP(path))) {
+      ERR(GRN_NO_MEMORY_AVAILABLE, "cannot duplicate path.");
+      return GRN_NO_MEMORY_AVAILABLE;
+    }
+  } else {
+    path = NULL;
+  }
+  element_size = ra->header->element_size;
+  if ((rc = grn_io_close(ctx, ra->io))) { goto exit; }
+  ra->io = NULL;
+  if (path && (rc = grn_io_remove(ctx, path))) { goto exit; }
+  if (!_grn_ra_create(ctx, ra, path, element_size)) {
+    rc = GRN_UNKNOWN_ERROR;
+  }
+exit:
+  if (path) { GRN_FREE(path); }
+  return rc;
+}
+
 void *
 grn_ra_ref(grn_ctx *ctx, grn_ra *ra, grn_id id)
 {
@@ -272,12 +307,12 @@ struct grn_ja_header {
 #define SEGMENTS_GINFO_ON(ja,seg,width) (SEGMENTS_AT(ja,seg) = SEG_GINFO|(width))
 #define SEGMENTS_OFF(ja,seg) (SEGMENTS_AT(ja,seg) = 0)
 
-grn_ja *
-grn_ja_create(grn_ctx *ctx, const char *path, unsigned int max_element_size, uint32_t flags)
+static grn_ja *
+_grn_ja_create(grn_ctx *ctx, grn_ja *ja, const char *path,
+               unsigned int max_element_size, uint32_t flags)
 {
   int i;
   grn_io *io;
-  grn_ja *ja = NULL;
   struct grn_ja_header *header;
   io = grn_io_create(ctx, path, sizeof(struct grn_ja_header),
                      JA_SEGMENT_SIZE, JA_N_DSEGMENTS, grn_io_auto,
@@ -288,10 +323,6 @@ grn_ja_create(grn_ctx *ctx, const char *path, unsigned int max_element_size, uin
   header->curr_pos = JA_SEGMENT_SIZE;
   header->flags = flags;
   for (i = 0; i < JA_N_ESEGMENTS; i++) { header->esegs[i] = JA_ESEG_VOID; }
-  if (!(ja = GRN_GMALLOC(sizeof(grn_ja)))) {
-    grn_io_close(ctx, io);
-    return NULL;
-  }
   GRN_DB_OBJ_SET_TYPE(ja, GRN_COLUMN_VAR_SIZE);
   ja->io = io;
   ja->header = header;
@@ -302,6 +333,20 @@ grn_ja_create(grn_ctx *ctx, const char *path, unsigned int max_element_size, uin
 }
 
 grn_ja *
+grn_ja_create(grn_ctx *ctx, const char *path, unsigned int max_element_size, uint32_t flags)
+{
+  grn_ja *ja = NULL;
+  if (!(ja = GRN_GMALLOC(sizeof(grn_ja)))) {
+    return NULL;
+  }
+  if (!_grn_ja_create(ctx, ja, path, max_element_size, flags)) {
+    GRN_FREE(ja);
+    return NULL;
+  }
+  return ja;
+}
+
+grn_ja *
 grn_ja_open(grn_ctx *ctx, const char *path)
 {
   grn_io *io;
@@ -350,6 +395,34 @@ grn_ja_remove(grn_ctx *ctx, const char *path)
   return grn_io_remove(ctx, path);
 }
 
+grn_rc
+grn_ja_truncate(grn_ctx *ctx, grn_ja *ja)
+{
+  grn_rc rc;
+  char *path;
+  unsigned int max_element_size;
+  uint32_t flags;
+  if ((path = (char *)grn_io_path(ja->io)) && *path != '\0') {
+    if (!(path = GRN_STRDUP(path))) {
+      ERR(GRN_NO_MEMORY_AVAILABLE, "cannot duplicate path.");
+      return GRN_NO_MEMORY_AVAILABLE;
+    }
+  } else {
+    path = NULL;
+  }
+  max_element_size = ja->header->max_element_size;
+  flags = ja->header->flags;
+  if ((rc = grn_io_close(ctx, ja->io))) { goto exit; }
+  ja->io = NULL;
+  if (path && (rc = grn_io_remove(ctx, path))) { goto exit; }
+  if (!_grn_ja_create(ctx, ja, path, max_element_size, flags)) {
+    rc = GRN_UNKNOWN_ERROR;
+  }
+exit:
+  if (path) { GRN_FREE(path); }
+  return rc;
+}
+
 static void *
 grn_ja_ref_raw(grn_ctx *ctx, grn_ja *ja, grn_id id, grn_io_win *iw, uint32_t *value_len)
 {




Groonga-commit メーリングリストの案内
Back to archive index