Просмотр исходного кода

structure: BStringTrie: use less memory (half)

ambrop7 13 лет назад
Родитель
Сommit
2dec1188f0
1 измененных файлов с 14 добавлено и 25 удалено
  1. 14 25
      structure/BStringTrie.h

+ 14 - 25
structure/BStringTrie.h

@@ -39,18 +39,16 @@
 
 #define BSTRINGTRIE_DEFAULT_VALUE ((int)-1)
 
-#define BSTRINGTRIE_DEGREE (((size_t)1) << CHAR_BIT)
+#define BSTRINGTRIE_DEGREE ((((size_t)1) << CHAR_BIT) - 1)
 
 struct BStringTrie__node {
-    int value[BSTRINGTRIE_DEGREE];
-    int link[BSTRINGTRIE_DEGREE];
+    int value_links[1 + BSTRINGTRIE_DEGREE];
 };
 
 typedef struct {
     struct BStringTrie__node *arr;
     size_t count;
     size_t capacity;
-    int empty_value;
 } BStringTrie;
 
 static int BStringTrie_Init (BStringTrie *o) WARN_UNUSED;
@@ -86,9 +84,10 @@ static int BStringTrie__new_node (BStringTrie *o, int *out_nodeidx)
     
     struct BStringTrie__node *node = &o->arr[o->count];
     
+    node->value_links[0] = BSTRINGTRIE_DEFAULT_VALUE;
+    
     for (size_t i = 0; i < BSTRINGTRIE_DEGREE; i++) {
-        node->value[i] = BSTRINGTRIE_DEFAULT_VALUE;
-        node->link[i] = -1;
+        node->value_links[1 + i] = -1;
     }
     
     *out_nodeidx = o->count;
@@ -101,7 +100,6 @@ static int BStringTrie_Init (BStringTrie *o)
 {
     o->count = 0;
     o->capacity = 1;
-    o->empty_value = BSTRINGTRIE_DEFAULT_VALUE;
     
     if (!(o->arr = BAllocArray(o->capacity, sizeof(o->arr[0])))) {
         return 0;
@@ -122,26 +120,21 @@ static int BStringTrie_Set (BStringTrie *o, const char *key, int value)
 {
     ASSERT(key)
     
-    if (!*key) {
-        o->empty_value = value;
-        return 1;
-    }
-    
     const unsigned char *ukey = (const unsigned char *)key;
     int nodeidx = 0;
     
-    while (*(ukey + 1)) {
-        ASSERT(o->arr[nodeidx].link[*ukey] >= -1)
+    while (*ukey) {
+        ASSERT(o->arr[nodeidx].value_links[*ukey] >= -1)
         
         int new_nodeidx;
         
-        if (o->arr[nodeidx].link[*ukey] >= 0) {
-            new_nodeidx = o->arr[nodeidx].link[*ukey];
+        if (o->arr[nodeidx].value_links[*ukey] >= 0) {
+            new_nodeidx = o->arr[nodeidx].value_links[*ukey];
         } else {
             if (!BStringTrie__new_node(o, &new_nodeidx)) {
                 return 0;
             }
-            o->arr[nodeidx].link[*ukey] = new_nodeidx;
+            o->arr[nodeidx].value_links[*ukey] = new_nodeidx;
         }
         
         ASSERT(new_nodeidx >= 0)
@@ -151,7 +144,7 @@ static int BStringTrie_Set (BStringTrie *o, const char *key, int value)
         ukey++;
     }
     
-    o->arr[nodeidx].value[*ukey] = value;
+    o->arr[nodeidx].value_links[0] = value;
     
     return 1;
 }
@@ -160,15 +153,11 @@ static int BStringTrie_Lookup (const BStringTrie *o, const char *key)
 {
     ASSERT(key)
     
-    if (!*key) {
-        return o->empty_value;
-    }
-    
     const unsigned char *ukey = (const unsigned char *)key;
     int nodeidx = 0;
     
-    while (*(ukey + 1)) {
-        nodeidx = o->arr[nodeidx].link[*ukey];
+    while (*ukey) {
+        nodeidx = o->arr[nodeidx].value_links[*ukey];
         ASSERT(nodeidx >= -1)
         if (nodeidx < 0) {
             return -1;
@@ -177,7 +166,7 @@ static int BStringTrie_Lookup (const BStringTrie *o, const char *key)
         ukey++;
     }
     
-    return o->arr[nodeidx].value[*ukey];
+    return o->arr[nodeidx].value_links[0];
 }
 
 #endif