[Julius-cvs 268] CVS update: julius4/libsent/src/util

アーカイブの一覧に戻る

sumom****@users***** sumom****@users*****
2008年 9月 30日 (火) 12:58:18 JST


Index: julius4/libsent/src/util/aptree.c
diff -u julius4/libsent/src/util/aptree.c:1.2 julius4/libsent/src/util/aptree.c:1.3
--- julius4/libsent/src/util/aptree.c:1.2	Tue Dec 18 17:45:54 2007
+++ julius4/libsent/src/util/aptree.c	Tue Sep 30 12:58:18 2008
@@ -12,7 +12,7 @@
  * @author Akinobu LEE
  * @date   Thu Feb 17 15:21:53 2005
  *
- * $Revision: 1.2 $
+ * $Revision: 1.3 $
  * 
  */
 /*
@@ -32,11 +32,11 @@
  * @return pointer to the new node.
  */
 static APATNODE *
-new_node()
+new_node(BMALLOC_BASE **mroot)
 {
   APATNODE *tmp;
 
-  tmp = (APATNODE *)mymalloc(sizeof(APATNODE));
+  tmp = (APATNODE *)mybmalloc2(sizeof(APATNODE), mroot);
   tmp->left0 = NULL;
   tmp->right1 = NULL;
 
@@ -53,6 +53,21 @@
 static void *
 aptree_search_data_r(APATNODE *node, char *str, int maxbitplace)
 {
+#if 1
+  /* non-recursive */
+  APATNODE *n;
+  APATNODE *branch = NULL;
+  n = node;
+  while(n->left0 != NULL || n->right1 != NULL) {
+    branch = n;
+    if (testbit_max(str, n->value.thres_bit, maxbitplace) != 0) {
+      n = n->right1;
+    } else {
+      n = n->left0;
+    }
+  } 
+  return(n->value.data);
+#else
   if (node->left0 == NULL && node->right1 == NULL) {
     return(node->value.data);
   } else {
@@ -62,6 +77,7 @@
       return(aptree_search_data_r(node->left0, str, maxbitplace));
     }
   }
+#endif
 }
 
 /** 
@@ -94,11 +110,11 @@
  * @return the newly allocated root node.
  */
 APATNODE *
-aptree_make_root_node(void *data)
+aptree_make_root_node(void *data, BMALLOC_BASE **mroot)
 {
   APATNODE *nnew;
   /* make new leaf node for newstr */
-  nnew = new_node();
+  nnew = new_node(mroot);
   nnew->value.data = data;
   return(nnew);
 }
@@ -112,20 +128,54 @@
  * @param parentlink [i/o] the parent node to which this node will be added
  */
 static void
-aptree_add_entry_at(char *str, int bitloc, void *data, APATNODE **parentlink)
+aptree_add_entry_at(char *str, int slen, int bitloc, void *data, APATNODE **parentlink, BMALLOC_BASE **mroot)
 {
+#if 1
+  /* non-recursive */
+  APATNODE **p;
+  APATNODE *newleaf, *newbranch, *node;
+
+  p = parentlink;
+  node = *p;
+  while(node->value.thres_bit <= bitloc &&
+	(node->left0 != NULL || node->right1 != NULL)) {
+    if (testbit(str, slen, node->value.thres_bit) != 0) {
+      p = &(node->right1);
+    } else {
+      p = &(node->left0);
+    }
+    node = *p;
+  }
+	 
+  /* insert between [parent] and [node] */
+  newleaf = new_node(mroot);
+  newleaf->value.data = data;
+  newbranch = new_node(mroot);
+  newbranch->value.thres_bit = bitloc;
+  *p = newbranch;
+  if (testbit(str, slen, bitloc) ==0) {
+    newbranch->left0  = newleaf;
+    newbranch->right1 = node;
+  } else {
+    newbranch->left0  = node;
+    newbranch->right1 = newleaf;
+  }
+
+#else
+
   APATNODE *node;
+  APATNODE *newleaf, *newbranch;
+
   node = *parentlink;
   if (node->value.thres_bit > bitloc ||
       (node->left0 == NULL && node->right1 == NULL)) {
-    APATNODE *newleaf, *newbranch;
     /* insert between [parent] and [node] */
-    newleaf = new_node();
+    newleaf = new_node(mroot);
     newleaf->value.data = data;
-    newbranch = new_node();
+    newbranch = new_node(mroot);
     newbranch->value.thres_bit = bitloc;
     *parentlink = newbranch;
-    if (testbit(str, bitloc) ==0) {
+    if (testbit(str, slen, bitloc) ==0) {
       newbranch->left0  = newleaf;
       newbranch->right1 = node;
     } else {
@@ -134,12 +184,13 @@
     }
     return;
   } else {
-    if (testbit(str, node->value.thres_bit) != 0) {
-      aptree_add_entry_at(str, bitloc, data, &(node->right1));
+    if (testbit(str, slen, node->value.thres_bit) != 0) {
+      aptree_add_entry_at(str, slen, bitloc, data, &(node->right1), mroot);
     } else {
-      aptree_add_entry_at(str, bitloc, data, &(node->left0));
+      aptree_add_entry_at(str, slen, bitloc, data, &(node->left0), mroot);
     }
   }
+#endif
 }
 
 /** 
@@ -152,15 +203,15 @@
  * @param rootnode [i/o] pointer to root index node
  */
 void
-aptree_add_entry(char *str, void *data, char *matchstr, APATNODE **rootnode)
+aptree_add_entry(char *str, void *data, char *matchstr, APATNODE **rootnode, BMALLOC_BASE **mroot)
 {
   int bitloc;
 
   bitloc = where_the_bit_differ(str, matchstr);
   if (*rootnode == NULL) {
-    *rootnode = aptree_make_root_node(data);
+    *rootnode = aptree_make_root_node(data, mroot);
   } else {
-    aptree_add_entry_at(str, bitloc, data, rootnode);
+    aptree_add_entry_at(str, strlen(str), bitloc, data, rootnode, mroot);
   }
 
 }
@@ -184,14 +235,14 @@
     /* make sure the data of your removal request already exists before call this */
     /* execute removal */
     if (up == NULL) {
-      free(now);
+      //free(now);
       *root = NULL;
       return;
     }
     b = (up->right1 == now) ? up->left0 : up->right1;
     if (up2 == NULL) {
-      free(now);
-      free(up);
+      //free(now);
+      //free(up);
       *root = b;
       return;
     }
@@ -200,8 +251,8 @@
     } else {
       up2->right1 = b;
     }
-    free(now);
-    free(up);
+    //free(now);
+    //free(up);
     return;
   } else {
     /* traverse */
@@ -254,16 +305,219 @@
   }
 }
 
-/** 
- * Free all the sub nodes from specified node.
- * 
- * @param node [in] current node.
- */
-void
-free_aptree(APATNODE *node)
+/*************************************************************/
+
+static void
+aptree_count(APATNODE *node, int *count_branch, int *count_data, int *maxbit)
+{
+  if (node->left0 == NULL && node->right1 == NULL) {
+    (*count_data)++;
+  } else {
+    if (node->value.thres_bit > *maxbit) {
+      *maxbit = node->value.thres_bit;
+    }
+    (*count_branch)++;
+    if (node->left0 != NULL) {
+      aptree_count(node->left0, count_branch, count_data, maxbit);
+    }
+    if (node->right1 != NULL) {
+      aptree_count(node->right1, count_branch, count_data, maxbit);
+    }
+  }
+}  
+
+static int
+aptree_build_index(APATNODE *node, int *num, int *data_id, int *left, int *right, int *data)
+{
+  int id;
+
+  id = *num;
+  (*num)++;
+  if (node->left0 == NULL && node->right1 == NULL) {
+    left[id] = -1;
+    right[id] = -1;
+    data[id] = *data_id;
+    /* node->value.data を保存 */
+    (*data_id)++;
+  } else {
+    data[id] = node->value.thres_bit;
+    if (node->left0 != NULL) {
+      left[id] = aptree_build_index(node->left0, num, data_id, left, right, data);
+    } else {
+      left[id] = -1;
+    }
+    if (node->right1 != NULL) {
+      right[id] = aptree_build_index(node->right1, num, data_id, left, right, data);
+    } else {
+      right[id] = -1;
+    }
+  }
+  return id;
+}  
+
+static void
+aptree_write_leaf(FILE *fp, APATNODE *node, boolean (*callback)(void *, FILE *fp), boolean *error_p)
+{
+  if (node->left0 == NULL && node->right1 == NULL) {
+    if ((*callback)(node->value.data, fp) == FALSE) {
+      *error_p = TRUE;
+    }
+  } else {
+    if (node->left0 != NULL) {
+      aptree_write_leaf(fp, node->left0, callback, error_p);
+    }
+    if (node->right1 != NULL) {
+      aptree_write_leaf(fp, node->right1, callback, error_p);
+    }
+  }
+}
+
+
+boolean
+aptree_write(FILE *fp, APATNODE *root, boolean (*save_data_func)(void *, FILE *fp))
+{
+  int count_node, count_branch, count_data, maxbit;
+  int *left, *right, *value;
+  int num, did;
+  boolean err;
+
+  if (root == NULL) return TRUE;
+
+  /* count statistics */
+  count_branch = count_data = 0;
+  maxbit = 0;
+  aptree_count(root, &count_branch, &count_data, &maxbit);
+  count_node = count_branch + count_data;
+  jlog("Stat: aptree_write: %d nodes (%d branch + %d data), maxbit=%d\n", count_node, count_branch, count_data, maxbit);
+  /* allocate */
+  left = (int *)mymalloc(sizeof(int) * count_node);
+  right = (int *)mymalloc(sizeof(int) * count_node);
+  value = (int *)mymalloc(sizeof(int) * count_node);
+  /* make index */
+  did = num = 0;
+  aptree_build_index(root, &num, &did, left, right, value);
+#if 0
+  {
+    int i;
+    for(i=0;i<count_node;i++) {
+      printf("%d: %d %d %d\n", i, left[i], right[i], value[i]);
+    }
+  }
+#endif
+  /* write tree to file */
+  if (myfwrite(&count_node, sizeof(int), 1, fp) < 1) {
+    jlog("Error: aptree_write: fail to write header\n");
+    return FALSE;
+  }
+  if (myfwrite(&count_data, sizeof(int), 1, fp) < 1) {
+    jlog("Error: aptree_write: fail to write header\n");
+    return FALSE;
+  }
+  if (myfwrite(left, sizeof(int), count_node, fp) < count_node) {
+    jlog("Error: aptree_write: fail to write %d bytes\n", sizeof(int) * count_node);
+    return FALSE;
+  }
+  if (myfwrite(right, sizeof(int), count_node, fp) < count_node) {
+    jlog("Error: aptree_write: fail to write %d bytes\n", sizeof(int) * count_node);
+    return FALSE;
+  }
+  if (myfwrite(value, sizeof(int), count_node, fp) < count_node) {
+    jlog("Error: aptree_write: fail to write %d bytes\n", sizeof(int) * count_node);
+    return FALSE;
+  }
+  if (save_data_func != NULL) {
+    /* write leaf node data */
+    err = FALSE;
+    aptree_write_leaf(fp, root, save_data_func, &err);
+  }
+  if (err) {
+    jlog("Error: aptree_write: error occured when writing tree leaf data\n");
+    return FALSE;
+  }
+
+  free(value);
+  free(right);
+  free(left);
+
+  return TRUE;
+}
+
+
+boolean
+aptree_read(FILE *fp, APATNODE **root, BMALLOC_BASE **mroot, void *data, boolean (*load_data_func)(void **, void *, FILE *))
 {
-  if (node == NULL) return;
-  if (node->left0 != NULL) free_aptree(node->left0);
-  if (node->right1 != NULL) free_aptree(node->right1);
-  free(node);
+  int count_node, count_branch, count_data, maxbit;
+  int *left, *right, *value;
+  int num, did;
+  boolean err;
+  APATNODE *nodelist;
+  APATNODE *node;
+  int i;
+
+  if (*root != NULL) {
+    jlog("Error: aptree_read: root node != NULL!\n");
+    return FALSE;
+  }
+
+  /* read header */
+  if (myfread(&count_node, sizeof(int), 1, fp) < 1) {
+    jlog("Error: aptree_read: fail to read header\n");
+    return FALSE;
+  }
+  if (myfread(&count_data, sizeof(int), 1, fp) < 1) {
+    jlog("Error: aptree_read: fail to read header\n");
+    return FALSE;
+  }
+  jlog("Stat: aptree_read: %d nodes (%d branch + %d data)\n",
+       count_node, count_node - count_data, count_data);
+  /* prepare buffer */
+  left = (int *)mymalloc(sizeof(int) * count_node);
+  right = (int *)mymalloc(sizeof(int) * count_node);
+  value = (int *)mymalloc(sizeof(int) * count_node);
+  /* read data */
+  if (myfread(left, sizeof(int), count_node, fp) < count_node) {
+    jlog("Error: aptree_read: fail to read %d bytes\n", sizeof(int) * count_node);
+    return FALSE;
+  }
+  if (myfread(right, sizeof(int), count_node, fp) < count_node) {
+    jlog("Error: aptree_read: fail to read %d bytes\n", sizeof(int) * count_node);
+    return FALSE;
+  }
+  if (myfread(value, sizeof(int), count_node, fp) < count_node) {
+    jlog("Error: aptree_read: fail to read %d bytes\n", sizeof(int) * count_node);
+    return FALSE;
+  }
+  /* allocate nodes */
+  nodelist = (APATNODE *)mybmalloc2(sizeof(APATNODE) * count_node, mroot);
+  for(i=0;i<count_node;i++) {
+    node = &(nodelist[i]);
+    if (left[i] == -1) {
+      node->left0 = NULL;
+    } else {
+      node->left0 = &(nodelist[left[i]]);
+    }
+    if (right[i] == -1) {
+      node->right1 = NULL;
+    } else {
+      node->right1 = &(nodelist[right[i]]);
+    }
+    if (left[i] == -1 && right[i] == -1) {
+      /* load leaf data node */
+      if ((*load_data_func)(&(node->value.data), data, fp) == FALSE) {
+	jlog("Error: aptree_read: failed to load leaf data entity\n");
+	return FALSE;
+      }
+    } else {
+      /* set thres bit */
+	node->value.thres_bit = value[i];
+    }
+  }
+  /* set root node */
+  *root = &(nodelist[0]);
+  
+  free(value);
+  free(right);
+  free(left);
+
+  return TRUE;
 }
Index: julius4/libsent/src/util/ptree.c
diff -u julius4/libsent/src/util/ptree.c:1.2 julius4/libsent/src/util/ptree.c:1.3
--- julius4/libsent/src/util/ptree.c:1.2	Tue Dec 18 17:45:54 2007
+++ julius4/libsent/src/util/ptree.c	Tue Sep 30 12:58:18 2008
@@ -12,7 +12,7 @@
  * @author Akinobu LEE
  * @date   Thu Feb 17 15:34:39 2005
  *
- * $Revision: 1.2 $
+ * $Revision: 1.3 $
  * 
  */
 /*
@@ -37,11 +37,11 @@
  * @return the content of tested bit in @a tmp_str, either 0 or 1.
  */
 int
-testbit(char *str, int bitplace)
+testbit(char *str, int slen, int bitplace)
 {
   int maskptr;
   
-  if ((maskptr = bitplace >> 3) > strlen(str)) return 0;
+  if ((maskptr = bitplace >> 3) > slen) return 0;
   return(str[maskptr] & mbit[bitplace & 7]);
 }
 
@@ -74,11 +74,14 @@
 {
   int p = 0;
   int bitloc;
+  int slen1, slen2;
 
   /* step: char, bit */
   while(str1[p] == str2[p]) p++;
   bitloc = p * 8;
-  while(testbit(str1, bitloc) == testbit(str2, bitloc)) bitloc++;
+  slen1 = strlen(str1);
+  slen2 = strlen(str2);
+  while(testbit(str1, slen1, bitloc) == testbit(str2, slen2, bitloc)) bitloc++;
 
   return(bitloc);
 }
@@ -138,7 +141,7 @@
 
   newnum = 0;
   for (i=0;i<wordsnum;i++) {
-    if (testbit(words[i], bitplace) != 0) {
+    if (testbit(words[i], strlen(words[i]), bitplace) != 0) {
       newnum++;
     }
   }
@@ -149,9 +152,9 @@
     /* sort word pointers by tested bit */
     j = wordsnum-1;
     for (i=0; i<newnum; i++) {
-      if (testbit(words[i], bitplace) == 0) {
+      if (testbit(words[i], strlen(words[i]), bitplace) == 0) {
 	for (; j>=newnum; j--) {
-	  if (testbit(words[j], bitplace) != 0) {
+	  if (testbit(words[j], strlen(words[j]), bitplace) != 0) {
 	    p = words[i]; words[i] = words[j]; words[j] = p;
 	    tmp = data[i]; data[i] = data[j]; data[j] = tmp;
 	    break;
@@ -267,7 +270,7 @@
  * @param parentlink [i/o] the parent node to which this node will be added
  */
 static void
-ptree_add_entry_at(char *str, int bitloc, int data, PATNODE **parentlink)
+ptree_add_entry_at(char *str, int slen, int bitloc, int data, PATNODE **parentlink)
 {
   PATNODE *node;
   node = *parentlink;
@@ -280,7 +283,7 @@
     newbranch = new_node();
     newbranch->value.thres_bit = bitloc;
     *parentlink = newbranch;
-    if (testbit(str, bitloc) ==0) {
+    if (testbit(str, slen, bitloc) ==0) {
       newbranch->left0  = newleaf;
       newbranch->right1 = node;
     } else {
@@ -289,10 +292,10 @@
     }
     return;
   } else {
-    if (testbit(str, node->value.thres_bit) != 0) {
-      ptree_add_entry_at(str, bitloc, data, &(node->right1));
+    if (testbit(str, slen, node->value.thres_bit) != 0) {
+      ptree_add_entry_at(str, slen, bitloc, data, &(node->right1));
     } else {
-      ptree_add_entry_at(str, bitloc, data, &(node->left0));
+      ptree_add_entry_at(str, slen, bitloc, data, &(node->left0));
     }
   }
 }
@@ -315,7 +318,7 @@
   if (*rootnode == NULL) {
     *rootnode = ptree_make_root_node(data);
   } else {
-    ptree_add_entry_at(str, bitloc, data, rootnode);
+    ptree_add_entry_at(str, strlen(str), bitloc, data, rootnode);
   }
 
 }


Julius-cvs メーリングリストの案内
アーカイブの一覧に戻る