[Groonga-commit] groonga/groonga [master] Add grn_array_set_value_inline() to skip unnecessary checks.

Back to archive index

null+****@clear***** null+****@clear*****
2012年 4月 3日 (火) 16:08:26 JST


Susumu Yata	2012-04-03 16:08:26 +0900 (Tue, 03 Apr 2012)

  New Revision: 8604526e4d74c2f61c8b0860d1012119a8953569

  Log:
    Add grn_array_set_value_inline() to skip unnecessary checks.

  Modified files:
    lib/hash.c

  Modified: lib/hash.c (+56 -45)
===================================================================
--- lib/hash.c    2012-04-03 15:37:35 +0900 (b324e70)
+++ lib/hash.c    2012-04-03 16:08:26 +0900 (9554542)
@@ -517,9 +517,6 @@ grn_array_get_value_inline(grn_ctx *ctx, grn_array *array, grn_id id)
   if (!ctx || !array) {
     return NULL;
   }
-  if (id == 0 || id > grn_array_get_max_id(array)) {
-    return NULL;
-  }
   if (*array->n_garbages) {
     /*
      * grn_array_bitmap_at() is a time-consuming function, so it is called only
@@ -528,6 +525,8 @@ grn_array_get_value_inline(grn_ctx *ctx, grn_array *array, grn_id id)
     if (grn_array_bitmap_at(ctx, array, id) != 1) {
       return NULL;
     }
+  } else if (id == 0 || id > grn_array_get_max_id(array)) {
+    return NULL;
   }
   return grn_array_entry_at(ctx, array, id, 0);
 }
@@ -551,6 +550,49 @@ _grn_array_get_value(grn_ctx *ctx, grn_array *array, grn_id id)
   return grn_array_get_value_inline(ctx, array, id);
 }
 
+inline static grn_rc
+grn_array_set_value_inline(grn_ctx *ctx, grn_array *array, grn_id id,
+                           const void *value, int flags)
+{
+  void * const entry = grn_array_entry_at(ctx, array, id, 0);
+  if (!entry) {
+    return GRN_NO_MEMORY_AVAILABLE;
+  }
+
+  switch ((flags & GRN_OBJ_SET_MASK)) {
+  case GRN_OBJ_SET :
+    memcpy(entry, value, array->value_size);
+    return GRN_SUCCESS;
+  case GRN_OBJ_INCR :
+    switch (array->value_size) {
+  case sizeof(int32_t) :
+      *((int32_t *)entry) += *((int32_t *)value);
+      return GRN_SUCCESS;
+    case sizeof(int64_t) :
+      *((int64_t *)entry) += *((int64_t *)value);
+      return GRN_SUCCESS;
+    default :
+      return GRN_INVALID_ARGUMENT;
+    }
+    break;
+  case GRN_OBJ_DECR :
+    switch (array->value_size) {
+    case sizeof(int32_t) :
+      *((int32_t *)entry) -= *((int32_t *)value);
+      return GRN_SUCCESS;
+    case sizeof(int64_t) :
+      *((int64_t *)entry) -= *((int64_t *)value);
+      return GRN_SUCCESS;
+    default :
+      return GRN_INVALID_ARGUMENT;
+    }
+    break;
+  default :
+    // todo : support other types.
+    return GRN_INVALID_ARGUMENT;
+  }
+}
+
 grn_rc
 grn_array_set_value(grn_ctx *ctx, grn_array *array, grn_id id,
                     const void *value, int flags)
@@ -558,50 +600,18 @@ grn_array_set_value(grn_ctx *ctx, grn_array *array, grn_id id,
   if (!ctx || !array || !value) {
     return GRN_INVALID_ARGUMENT;
   }
-  /* TODO: Use *n_garbages to skip grn_array_bitmap_at(). */
-  if (grn_array_bitmap_at(ctx, array, id) != 1) {
-    return GRN_INVALID_ARGUMENT;
-  }
-
-  {
-    void * const entry = grn_array_entry_at(ctx, array, id, 0);
-    if (!entry) {
-      return GRN_NO_MEMORY_AVAILABLE;
-    }
-
-    switch ((flags & GRN_OBJ_SET_MASK)) {
-    case GRN_OBJ_SET :
-      memcpy(entry, value, array->value_size);
-      return GRN_SUCCESS;
-    case GRN_OBJ_INCR :
-      switch (array->value_size) {
-      case sizeof(int32_t) :
-        *((int32_t *)entry) += *((int32_t *)value);
-        return GRN_SUCCESS;
-      case sizeof(int64_t) :
-        *((int64_t *)entry) += *((int64_t *)value);
-        return GRN_SUCCESS;
-      default :
-        return GRN_INVALID_ARGUMENT;
-      }
-      break;
-    case GRN_OBJ_DECR :
-      switch (array->value_size) {
-      case sizeof(int32_t) :
-        *((int32_t *)entry) -= *((int32_t *)value);
-        return GRN_SUCCESS;
-      case sizeof(int64_t) :
-        *((int64_t *)entry) -= *((int64_t *)value);
-        return GRN_SUCCESS;
-      default :
-        return GRN_INVALID_ARGUMENT;
-      }
-      break;
-    default :
-      // todo : support other types.
+  if (*array->n_garbages) {
+    /*
+     * grn_array_bitmap_at() is a time-consuming function, so it is called only
+     * when there are garbages in the array.
+     */
+    if (grn_array_bitmap_at(ctx, array, id) != 1) {
       return GRN_INVALID_ARGUMENT;
     }
+  } else if (id == 0 || id > grn_array_get_max_id(array)) {
+    return GRN_INVALID_ARGUMENT;
   }
+  return grn_array_set_value_inline(ctx, array, id, value, flags);
 }
 
 grn_rc
@@ -802,7 +812,8 @@ grn_rc
 grn_array_cursor_set_value(grn_ctx *ctx, grn_array_cursor *cursor,
                            const void *value, int flags)
 {
-  return grn_array_set_value(ctx, cursor->array, cursor->curr_rec, value, flags);
+  return grn_array_set_value_inline(ctx, cursor->array, cursor->curr_rec,
+                                    value, flags);
 }
 
 grn_rc




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