[Groonga-commit] groonga/groonga [master] Use grn_hash_entry in grn_hash_add().

Back to archive index

null+****@clear***** null+****@clear*****
2012年 4月 4日 (水) 18:31:09 JST


Susumu Yata	2012-04-04 18:31:09 +0900 (Wed, 04 Apr 2012)

  New Revision: cd762e469b1e4f9aabdd145cb2bdab8fbc1c5a9e

  Log:
    Use grn_hash_entry in grn_hash_add().

  Modified files:
    lib/hash.c

  Modified: lib/hash.c (+74 -39)
===================================================================
--- lib/hash.c    2012-04-04 16:37:40 +0900 (9f277a2)
+++ lib/hash.c    2012-04-04 18:31:09 +0900 (1da13bb)
@@ -1772,66 +1772,101 @@ grn_hash_clear_lock(grn_ctx *ctx, grn_hash *hash)
   return GRN_SUCCESS;
 }
 
+
 grn_id
 grn_hash_add(grn_ctx *ctx, grn_hash *hash, const void *key,
              unsigned int key_size, void **value, int *added)
 {
-  entry_str *ee;
-  uint32_t h, i, m, s;
-  grn_id e, *ep, *np = NULL;
-  if (!key || !key_size) { return GRN_ID_NIL; }
+  uint32_t hash_value;
+  if (!key || !key_size) {
+    return GRN_ID_NIL;
+  }
   if (hash->obj.header.flags & GRN_OBJ_KEY_VAR_SIZE) {
     if (key_size > hash->key_size) {
       ERR(GRN_INVALID_ARGUMENT, "too long key");
       return GRN_ID_NIL;
     }
-    h = grn_hash_calculate_hash_value(key, key_size);
+    hash_value = grn_hash_calculate_hash_value(key, key_size);
   } else {
     if (key_size != hash->key_size) {
       ERR(GRN_INVALID_ARGUMENT, "key size unmatch");
       return GRN_ID_NIL;
     }
     if (key_size == sizeof(uint32_t)) {
-      h = *((uint32_t *)key);
+      hash_value = *((uint32_t *)key);
     } else {
-      h = grn_hash_calculate_hash_value(key, key_size);
+      hash_value = grn_hash_calculate_hash_value(key, key_size);
     }
   }
-  s = grn_hash_calculate_step(h);
-  /* lock */
-  if ((*hash->n_entries + *hash->n_garbages) * 2 > *hash->max_offset) {
-    grn_hash_reset(ctx, hash, 0);
-  }
-  m = *hash->max_offset;
-  for (i = h; ; i += s) {
-    if (!(ep = grn_hash_idx_at(ctx, hash, i))) { return GRN_ID_NIL; }
-    if (!(e = *ep)) { break; }
-    if (e == GARBAGE) {
-      if (!np) { np = ep; }
-      continue;
+
+  {
+    uint32_t i;
+    const uint32_t step = grn_hash_calculate_step(hash_value);
+    grn_id id, *index, *garbage_index = NULL;
+    grn_hash_entry *entry;
+
+    /* lock */
+    if ((*hash->n_entries + *hash->n_garbages) * 2 > *hash->max_offset) {
+      grn_hash_reset(ctx, hash, 0);
+    }
+
+    for (i = hash_value; ; i += step) {
+      index = grn_hash_idx_at(ctx, hash, i);
+      if (!index) {
+        return GRN_ID_NIL;
+      }
+      id = *index;
+      if (!id) {
+        break;
+      }
+      if (id == GARBAGE) {
+        if (!garbage_index) {
+          garbage_index = index;
+        }
+        continue;
+      }
+
+      entry = grn_hash_entry_at(ctx, hash, id, GRN_TABLE_ADD);
+      if (!entry) {
+        return GRN_ID_NIL;
+      }
+      if (grn_hash_entry_compare_key(ctx, hash, entry, hash_value,
+                                     key, key_size)) {
+        if (value) {
+          *value = grn_hash_entry_get_value(hash, entry);
+        }
+        if (added) {
+          *added = 0;
+        }
+        return id;
+      }
     }
-    ee = grn_hash_entry_at(ctx, hash, e, GRN_TABLE_ADD);
-    if (!ee) { return GRN_ID_NIL; }
-    if (match_key(ctx, hash, ee, h, key, key_size)) {
-      if (added) { *added = 0; }
-      goto exit;
+
+    id = entry_new(ctx, hash, key_size);
+    if (!id) {
+      return GRN_ID_NIL;
     }
+    entry = grn_hash_entry_at(ctx, hash, id, GRN_TABLE_ADD);
+    if (!entry) {
+      return GRN_ID_NIL;
+    }
+    grn_hash_entry_put_key(ctx, hash, entry, hash_value, key, key_size);
+    if (garbage_index) {
+      (*hash->n_garbages)--;
+      index = garbage_index;
+    }
+    *index = id;
+    (*hash->n_entries)++;
+    /* unlock */
+
+    if (value) {
+      *value = grn_hash_entry_get_value(hash, entry);
+    }
+    if (added) {
+      *added = 1;
+    }
+    return id;
   }
-  if (!(e = entry_new(ctx, hash, key_size))) { /* unlock */ return GRN_ID_NIL; }
-  ee = grn_hash_entry_at(ctx, hash, e, GRN_TABLE_ADD);
-  if (!ee) { return GRN_ID_NIL; }
-  put_key(ctx, hash, ee, h, key, key_size);
-  if (np) {
-    (*hash->n_garbages)--;
-    ep = np;
-  }
-  *ep = e;
-  (*hash->n_entries)++;
-  if (added) { *added = 1; }
-exit :
-  /* unlock */
-  if (value) { *value = get_value(hash,ee); }
-  return e;
 }
 
 grn_id




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