ソースを参照

ncd: NCDInterpProcess: handcraft a hash table instead of using CHash (it's less code)

ambrop7 13 年 前
コミット
3c304cdc77
3 ファイル変更21 行追加34 行削除
  1. 19 14
      ncd/NCDInterpProcess.c
  2. 2 7
      ncd/NCDInterpProcess.h
  3. 0 13
      ncd/NCDInterpProcess_hash.h

+ 19 - 14
ncd/NCDInterpProcess.c

@@ -33,7 +33,6 @@
 #include <stdlib.h>
 #include <stdlib.h>
 
 
 #include <misc/balloc.h>
 #include <misc/balloc.h>
-#include <misc/hashfun.h>
 #include <misc/maxalign.h>
 #include <misc/maxalign.h>
 #include <misc/strdup.h>
 #include <misc/strdup.h>
 #include <base/BLog.h>
 #include <base/BLog.h>
@@ -43,9 +42,6 @@
 
 
 #include <generated/blog_channel_ncd.h>
 #include <generated/blog_channel_ncd.h>
 
 
-#include "NCDInterpProcess_hash.h"
-#include <structure/CHash_impl.h>
-
 static int compute_prealloc (NCDInterpProcess *o)
 static int compute_prealloc (NCDInterpProcess *o)
 {
 {
     int size = 0;
     int size = 0;
@@ -168,11 +164,17 @@ int NCDInterpProcess_Init (NCDInterpProcess *o, NCDProcess *process, NCDStringIn
         goto fail0;
         goto fail0;
     }
     }
     
     
-    if (!NCDInterpProcess__Hash_Init(&o->hash, num_stmts)) {
-        BLog(BLOG_ERROR, "NCDInterpProcess__Hash_Init failed");
+    o->num_hash_buckets = num_stmts;
+    
+    if (!(o->hash_buckets = BAllocArray(o->num_hash_buckets, sizeof(o->hash_buckets[0])))) {
+        BLog(BLOG_ERROR, "BAllocArray failed");
         goto fail1;
         goto fail1;
     }
     }
     
     
+    for (size_t i = 0; i < o->num_hash_buckets; i++) {
+        o->hash_buckets[i] = -1;
+    }
+    
     if (!(o->name = b_strdup(NCDProcess_Name(process)))) {
     if (!(o->name = b_strdup(NCDProcess_Name(process)))) {
         BLog(BLOG_ERROR, "b_strdup failed");
         BLog(BLOG_ERROR, "b_strdup failed");
         goto fail2;
         goto fail2;
@@ -245,8 +247,9 @@ int NCDInterpProcess_Init (NCDInterpProcess *o, NCDProcess *process, NCDStringIn
         }
         }
         
         
         if (e->name >= 0) {
         if (e->name >= 0) {
-            NCDInterpProcess__HashRef ref = {e, o->num_stmts};
-            NCDInterpProcess__Hash_InsertMulti(&o->hash, o->stmts, ref);
+            size_t bucket_idx = e->name % o->num_hash_buckets;
+            e->hash_next = o->hash_buckets[bucket_idx];
+            o->hash_buckets[bucket_idx] = o->num_stmts;
         }
         }
         
         
         o->num_stmts++;
         o->num_stmts++;
@@ -278,7 +281,7 @@ fail3:
     }
     }
     free(o->name);
     free(o->name);
 fail2:
 fail2:
-    NCDInterpProcess__Hash_Free(&o->hash);
+    BFree(o->hash_buckets);
 fail1:
 fail1:
     BFree(o->stmts);
     BFree(o->stmts);
 fail0:
 fail0:
@@ -298,7 +301,7 @@ void NCDInterpProcess_Free (NCDInterpProcess *o)
     }
     }
     
     
     free(o->name);
     free(o->name);
-    NCDInterpProcess__Hash_Free(&o->hash);
+    BFree(o->hash_buckets);
     BFree(o->stmts);
     BFree(o->stmts);
 }
 }
 
 
@@ -308,17 +311,19 @@ int NCDInterpProcess_FindStatement (NCDInterpProcess *o, int from_index, NCD_str
     ASSERT(from_index >= 0)
     ASSERT(from_index >= 0)
     ASSERT(from_index <= o->num_stmts)
     ASSERT(from_index <= o->num_stmts)
     
     
-    int stmt_idx = NCDInterpProcess__Hash_Lookup(&o->hash, o->stmts, name).link;
+    size_t bucket_idx = name % o->num_hash_buckets;
+    int stmt_idx = o->hash_buckets[bucket_idx];
     ASSERT(stmt_idx >= -1)
     ASSERT(stmt_idx >= -1)
     ASSERT(stmt_idx < o->num_stmts)
     ASSERT(stmt_idx < o->num_stmts)
     
     
     while (stmt_idx >= 0) {
     while (stmt_idx >= 0) {
-        if (stmt_idx < from_index) {
+        if (stmt_idx < from_index && o->stmts[stmt_idx].name == name) {
             return stmt_idx;
             return stmt_idx;
         }
         }
         
         
-        NCDInterpProcess__HashRef ref = {&o->stmts[stmt_idx], stmt_idx};
-        stmt_idx = NCDInterpProcess__Hash_GetNextEqual(&o->hash, o->stmts, ref).link;
+        stmt_idx = o->stmts[stmt_idx].hash_next;
+        ASSERT(stmt_idx >= -1)
+        ASSERT(stmt_idx < o->num_stmts)
     }
     }
     
     
     return -1;
     return -1;

+ 2 - 7
ncd/NCDInterpProcess.h

@@ -33,7 +33,6 @@
 #include <stddef.h>
 #include <stddef.h>
 
 
 #include <misc/debug.h>
 #include <misc/debug.h>
-#include <structure/CHash.h>
 #include <base/DebugObject.h>
 #include <base/DebugObject.h>
 #include <ncd/NCDAst.h>
 #include <ncd/NCDAst.h>
 #include <ncd/NCDVal.h>
 #include <ncd/NCDVal.h>
@@ -61,11 +60,6 @@ struct NCDInterpProcess__stmt {
     int hash_next;
     int hash_next;
 };
 };
 
 
-typedef struct NCDInterpProcess__stmt *NCDInterpProcess_hash_arg;
-
-#include "NCDInterpProcess_hash.h"
-#include <structure/CHash_decl.h>
-
 /**
 /**
  * A data structure which contains information about a process or
  * A data structure which contains information about a process or
  * template, suitable for efficient interpretation. These structures
  * template, suitable for efficient interpretation. These structures
@@ -81,7 +75,8 @@ typedef struct {
     int num_stmts;
     int num_stmts;
     int prealloc_size;
     int prealloc_size;
     int is_template;
     int is_template;
-    NCDInterpProcess__Hash hash;
+    int *hash_buckets;
+    size_t num_hash_buckets;
     DebugObject d_obj;
     DebugObject d_obj;
 } NCDInterpProcess;
 } NCDInterpProcess;
 
 

+ 0 - 13
ncd/NCDInterpProcess_hash.h

@@ -1,13 +0,0 @@
-#define CHASH_PARAM_NAME NCDInterpProcess__Hash
-#define CHASH_PARAM_ENTRY struct NCDInterpProcess__stmt
-#define CHASH_PARAM_LINK int
-#define CHASH_PARAM_KEY NCD_string_id_t
-#define CHASH_PARAM_ARG NCDInterpProcess_hash_arg
-#define CHASH_PARAM_NULL ((int)-1)
-#define CHASH_PARAM_DEREF(arg, link) (&(arg)[(link)])
-#define CHASH_PARAM_ENTRYHASH(arg, entry) ((size_t)(entry).ptr->name)
-#define CHASH_PARAM_KEYHASH(arg, key) ((size_t)(key))
-#define CHASH_PARAM_ENTRYHASH_IS_CHEAP 0
-#define CHASH_PARAM_COMPARE_ENTRIES(arg, entry1, entry2) ((entry1).ptr->name == (entry2).ptr->name)
-#define CHASH_PARAM_COMPARE_KEY_ENTRY(arg, key1, entry2) ((key1) == (entry2).ptr->name)
-#define CHASH_PARAM_ENTRY_NEXT hash_next