Procházet zdrojové kódy

ncd: NCDInterpProcess: store statement names as id's and use a hash table not trie to look for them

ambrop7 před 13 roky
rodič
revize
de8f155c29

+ 21 - 34
ncd/NCDInterpProcess.c

@@ -43,8 +43,8 @@
 
 #include <generated/blog_channel_ncd.h>
 
-#include "NCDInterpProcess_trie.h"
-#include <structure/CStringTrie_impl.h>
+#include "NCDInterpProcess_hash.h"
+#include <structure/CHash_impl.h>
 
 static int compute_prealloc (NCDInterpProcess *o)
 {
@@ -168,8 +168,8 @@ int NCDInterpProcess_Init (NCDInterpProcess *o, NCDProcess *process, NCDStringIn
         goto fail0;
     }
     
-    if (!NCDInterpProcess__Trie_Init(&o->trie)) {
-        BLog(BLOG_ERROR, "NCDInterpProcess__Trie_Init failed");
+    if (!NCDInterpProcess__Hash_Init(&o->hash, num_stmts)) {
+        BLog(BLOG_ERROR, "NCDInterpProcess__Hash_Init failed");
         goto fail1;
     }
     
@@ -186,15 +186,18 @@ int NCDInterpProcess_Init (NCDInterpProcess *o, NCDProcess *process, NCDStringIn
         ASSERT(NCDStatement_Type(s) == NCDSTATEMENT_REG)
         struct NCDInterpProcess__stmt *e = &o->stmts[o->num_stmts];
         
-        e->name = NULL;
+        e->name = -1;
         e->cmdname = NULL;
         e->objnames = NULL;
         e->num_objnames = 0;
         e->alloc_size = 0;
         
-        if (NCDStatement_Name(s) && !(e->name = b_strdup(NCDStatement_Name(s)))) {
-            BLog(BLOG_ERROR, "b_strdup failed");
-            goto loop_fail0;
+        if (NCDStatement_Name(s)) {
+            e->name = NCDStringIndex_Get(string_index, NCDStatement_Name(s));
+            if (e->name < 0) {
+                BLog(BLOG_ERROR, "NCDStringIndex_Get failed");
+                goto loop_fail0;
+            }
         }
         
         if (!(e->cmdname = b_strdup(NCDStatement_RegCmdName(s)))) {
@@ -241,17 +244,9 @@ int NCDInterpProcess_Init (NCDInterpProcess *o, NCDProcess *process, NCDStringIn
             e->binding.simple_module = NCDModuleIndex_FindModule(module_index, NCDStatement_RegCmdName(s));
         }
         
-        if (e->name) {
-            int next_idx = NCDInterpProcess__Trie_Get(&o->trie, e->name);
-            ASSERT(next_idx >= -1)
-            ASSERT(next_idx < o->num_stmts)
-            
-            e->trie_next = next_idx;
-            
-            if (!NCDInterpProcess__Trie_Set(&o->trie, e->name, o->num_stmts)) {
-                BLog(BLOG_ERROR, "NCDInterpProcess__Trie_Set failed");
-                goto loop_fail3;
-            }
+        if (e->name >= 0) {
+            NCDInterpProcess__HashRef ref = {e, o->num_stmts};
+            NCDInterpProcess__Hash_InsertMulti(&o->hash, o->stmts, ref);
         }
         
         o->num_stmts++;
@@ -265,7 +260,6 @@ int NCDInterpProcess_Init (NCDInterpProcess *o, NCDProcess *process, NCDStringIn
         NCDValReplaceProg_Free(&e->arg_prog);
     loop_fail0:
         free(e->cmdname);
-        free(e->name);
         goto fail3;
     }
     
@@ -281,11 +275,10 @@ fail3:
         BFree(e->arg_data);
         NCDValReplaceProg_Free(&e->arg_prog);
         free(e->cmdname);
-        free(e->name);
     }
     free(o->name);
 fail2:
-    NCDInterpProcess__Trie_Free(&o->trie);
+    NCDInterpProcess__Hash_Free(&o->hash);
 fail1:
     BFree(o->stmts);
 fail0:
@@ -302,36 +295,30 @@ void NCDInterpProcess_Free (NCDInterpProcess *o)
         BFree(e->arg_data);
         NCDValReplaceProg_Free(&e->arg_prog);
         free(e->cmdname);
-        free(e->name);
     }
     
     free(o->name);
-    NCDInterpProcess__Trie_Free(&o->trie);
+    NCDInterpProcess__Hash_Free(&o->hash);
     BFree(o->stmts);
 }
 
-int NCDInterpProcess_FindStatement (NCDInterpProcess *o, int from_index, const char *name)
+int NCDInterpProcess_FindStatement (NCDInterpProcess *o, int from_index, NCD_string_id_t name)
 {
     DebugObject_Access(&o->d_obj);
     ASSERT(from_index >= 0)
     ASSERT(from_index <= o->num_stmts)
-    ASSERT(name)
     
-    int stmt_idx = NCDInterpProcess__Trie_Get(&o->trie, name);
+    int stmt_idx = NCDInterpProcess__Hash_Lookup(&o->hash, o->stmts, name).link;
     ASSERT(stmt_idx >= -1)
     ASSERT(stmt_idx < o->num_stmts)
     
     while (stmt_idx >= 0) {
-        struct NCDInterpProcess__stmt *e = &o->stmts[stmt_idx];
-        ASSERT(e->name)
-        
-        if (!strcmp(e->name, name) && stmt_idx < from_index) {
+        if (stmt_idx < from_index) {
             return stmt_idx;
         }
         
-        stmt_idx = e->trie_next;
-        ASSERT(stmt_idx >= -1)
-        ASSERT(stmt_idx < o->num_stmts)
+        NCDInterpProcess__HashRef ref = {&o->stmts[stmt_idx], stmt_idx};
+        stmt_idx = NCDInterpProcess__Hash_GetNextEqual(&o->hash, o->stmts, ref).link;
     }
     
     return -1;

+ 10 - 8
ncd/NCDInterpProcess.h

@@ -33,7 +33,7 @@
 #include <stddef.h>
 
 #include <misc/debug.h>
-#include <structure/CStringTrie.h>
+#include <structure/CHash.h>
 #include <base/DebugObject.h>
 #include <ncd/NCDAst.h>
 #include <ncd/NCDVal.h>
@@ -43,11 +43,8 @@
 #include <ncd/NCDStringIndex.h>
 #include <ncd/NCDMethodIndex.h>
 
-#include "NCDInterpProcess_trie.h"
-#include <structure/CStringTrie_decl.h>
-
 struct NCDInterpProcess__stmt {
-    char *name;
+    NCD_string_id_t name;
     char *cmdname;
     NCD_string_id_t *objnames;
     size_t num_objnames;
@@ -61,9 +58,14 @@ struct NCDInterpProcess__stmt {
     NCDValReplaceProg arg_prog;
     int alloc_size;
     int prealloc_offset;
-    int trie_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
  * template, suitable for efficient interpretation. These structures
@@ -79,13 +81,13 @@ typedef struct {
     int num_stmts;
     int prealloc_size;
     int is_template;
-    NCDInterpProcess__Trie trie;
+    NCDInterpProcess__Hash hash;
     DebugObject d_obj;
 } NCDInterpProcess;
 
 int NCDInterpProcess_Init (NCDInterpProcess *o, NCDProcess *process, NCDStringIndex *string_index, NCDPlaceholderDb *pdb, NCDModuleIndex *module_index, NCDMethodIndex *method_index) WARN_UNUSED;
 void NCDInterpProcess_Free (NCDInterpProcess *o);
-int NCDInterpProcess_FindStatement (NCDInterpProcess *o, int from_index, const char *name);
+int NCDInterpProcess_FindStatement (NCDInterpProcess *o, int from_index, NCD_string_id_t name);
 const char * NCDInterpProcess_StatementCmdName (NCDInterpProcess *o, int i);
 void NCDInterpProcess_StatementObjNames (NCDInterpProcess *o, int i, const NCD_string_id_t **out_objnames, size_t *out_num_objnames);
 const struct NCDModule * NCDInterpProcess_StatementGetSimpleModule (NCDInterpProcess *o, int i);

+ 13 - 0
ncd/NCDInterpProcess_hash.h

@@ -0,0 +1,13 @@
+#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

+ 0 - 4
ncd/NCDInterpProcess_trie.h

@@ -1,4 +0,0 @@
-#define CSTRINGTRIE_PARAM_NAME NCDInterpProcess__Trie
-#define CSTRINGTRIE_PARAM_VALUE int
-#define CSTRINGTRIE_PARAM_DEFAULT ((int)-1)
-#define CSTRINGTRIE_PARAM_SIGNIFICANT_BITS 3

+ 1 - 3
ncd/ncd.c

@@ -1199,9 +1199,7 @@ int process_find_object (struct process *p, int pos, NCD_string_id_t name, NCDOb
     ASSERT(pos <= p->num_statements)
     ASSERT(out_object)
     
-    const char *name_str = NCDStringIndex_Value(&string_index, name);
-    
-    int i = NCDInterpProcess_FindStatement(p->iprocess, pos, name_str);
+    int i = NCDInterpProcess_FindStatement(p->iprocess, pos, name);
     if (i >= 0) {
         struct statement *ps = &p->statements[i];
         ASSERT(i < p->num_statements)