]> git.sur5r.net Git - bacula/bacula/commitdiff
tree performance improvements
authorKern Sibbald <kern@sibbald.com>
Thu, 25 Mar 2004 14:50:31 +0000 (14:50 +0000)
committerKern Sibbald <kern@sibbald.com>
Thu, 25 Mar 2004 14:50:31 +0000 (14:50 +0000)
git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@1150 91ce42f0-d328-0410-95d8-f526ca767f89

bacula/src/lib/tree.c
bacula/src/lib/tree.h
bacula/src/version.h

index e13ae8c33b1771b45d78e7e2f7eb4eb2f8d6f73d..3fe73b472389837a38a3d8b97ca7d4fdf4c34a0c 100755 (executable)
@@ -5,7 +5,7 @@
  *
 */
 /*
-   Copyright (C) 2002-2003 Kern Sibbald and John Walker
+   Copyright (C) 2002-2004 Kern Sibbald and John Walker
 
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License as
 #include "bacula.h"
 #include "findlib/find.h"
             
-#ifndef MAXPATHLEN
-#define MAXPATHLEN 1000
-#endif
+/*
+ * Define PREPEND if you want the sibling list to
+ *  be prepended otherwise it will be appended when
+ *  a new entry is added.
+ */
+// #define PREPEND
+
+
+/* Forward referenced subroutines */
+static TREE_NODE *search_and_insert_tree_node(char *fname, int type, 
+              TREE_NODE *node, TREE_ROOT *root, TREE_NODE *parent);
 
 /*
  * NOTE !!!!! we turn off Debug messages for performance reasons.
@@ -170,7 +178,6 @@ void free_tree(TREE_ROOT *root)
 TREE_NODE *insert_tree_node(char *path, TREE_NODE *node, 
                            TREE_ROOT *root, TREE_NODE *parent)
 {
-   TREE_NODE *sibling;
    char *p, *q, *fname;
    int path_len = strlen(path);
 
@@ -216,21 +223,7 @@ TREE_NODE *insert_tree_node(char *path, TREE_NODE *node,
       Dmsg1(100, "No / found: %s\n", path);
    }
 
-   uint16_t fname_len = strlen(fname);
-   for (sibling=parent->child; sibling; sibling=sibling->sibling) {
-      Dmsg2(100, "sibling->fname=%s fname=%s\n", sibling->fname, fname);
-      if (sibling->fname_len == fname_len &&
-         strcmp(sibling->fname, fname) == 0) {
-         Dmsg1(100, "make_tree_path: found parent=%s\n", parent->fname);
-        if (q) {                     /* if trailing slash on entry */
-            *q = '/';                 /*  restore it */
-        }
-        return sibling;
-      }
-   }
-
-   append_tree_node(fname, node, root, parent);
-   Dmsg1(100, "insert_tree_node: parent=%s\n", parent->fname);
+   node = search_and_insert_tree_node(fname, 0, node, root, parent);
    if (q) {                          /* if trailing slash on entry */
       *q = '/';                       /*  restore it */
    }
@@ -243,7 +236,7 @@ TREE_NODE *insert_tree_node(char *path, TREE_NODE *node,
  */
 TREE_NODE *make_tree_path(char *path, TREE_ROOT *root)
 {
-   TREE_NODE *parent, *sibling, *node;
+   TREE_NODE *parent, *node;
    char *fname, *p;
    int type = TN_NEWDIR;
 
@@ -263,8 +256,20 @@ TREE_NODE *make_tree_path(char *path, TREE_ROOT *root)
       parent = (TREE_NODE *)root;
       type = TN_DIR_NLS;
    }
-   /* Is it already a sibling? */
+   node = search_and_insert_tree_node(fname, type, NULL, root, parent);
+   return node;
+}  
+
+/*
+ *  See if the fname already exists. If not insert a new node for it.
+ */
+static TREE_NODE *search_and_insert_tree_node(char *fname, int type, 
+              TREE_NODE *node, TREE_ROOT *root, TREE_NODE *parent)
+{
+   TREE_NODE *sibling, *last_sibling;
    uint16_t fname_len = strlen(fname);
+
+   /* Is it already a sibling? */
    for (sibling=parent->child; sibling; sibling=sibling->sibling) {
       Dmsg2(100, "sibling->fname=%s fname=%s\n", sibling->fname, fname);
       if (sibling->fname_len == fname_len &&
@@ -272,34 +277,29 @@ TREE_NODE *make_tree_path(char *path, TREE_ROOT *root)
          Dmsg1(100, "make_tree_path: found parent=%s\n", parent->fname);
         return sibling;
       }
+      last_sibling = sibling;
    }
    /* Must add */
-   node = new_tree_node(root, type);
-   append_tree_node(fname, node, root, parent);
-   Dmsg1(100, "make_tree_path: add parent=%s\n", node->fname);
-   return node;
-}  
-
-/*
- *  Append sibling to parent's child chain
- */
-void append_tree_node(char *fname, TREE_NODE *node, TREE_ROOT *root, TREE_NODE *parent)
-{
-   TREE_NODE *child;
-
+   if (!node) {
+      node = new_tree_node(root, type);
+   }
    Dmsg1(100, "append_tree_node: %s\n", fname);
-   node->fname_len = strlen(fname);
+   node->fname_len = fname_len;
    node->fname = tree_alloc(root, node->fname_len + 1);
    strcpy(node->fname, fname);
    node->parent = parent;
    if (!parent->child) {
       parent->child = node;
-      goto item_link;
+      goto item_link;                /* No children, so skip search */
    }
-   /* Append to end of sibling chain */
-   for (child=parent->child; child->sibling; child=child->sibling)
-      { }
-   child->sibling = node;
+
+#ifdef PREPEND
+   /* Add node to head of sibling chain */
+   node->sibling = parent->child;
+   parent->child = node;
+#else
+   last_sibling = node;
+#endif
 
    /* Maintain a linear chain of nodes */
 item_link:
@@ -310,7 +310,7 @@ item_link:
       root->last->next = node;
       root->last = node;
    }
-   return;
+   return node;
 }
 
 #ifdef SLOW_WAY
@@ -327,44 +327,6 @@ TREE_NODE *next_tree_node(TREE_NODE *node)
 #endif
 
 
-void print_tree(char *path, TREE_NODE *tree)
-{
-   char buf[MAXPATHLEN];
-   char *termchr;
-
-   if (!tree) {
-      return;
-   }
-   switch (tree->type) {
-   case TN_DIR_NLS:
-   case TN_DIR:
-   case TN_NEWDIR:  
-      termchr = "/";
-      break;
-   case TN_ROOT:
-   case TN_FILE:
-   default:
-      termchr = "";
-      break;
-   }
-   Dmsg3(-1, "%s/%s%s\n", path, tree->fname, termchr);
-   switch (tree->type) {
-   case TN_FILE:
-   case TN_NEWDIR:
-   case TN_DIR:
-   case TN_DIR_NLS:
-      bsnprintf(buf, sizeof(buf), "%s/%s", path, tree->fname);
-      print_tree(buf, tree->child);
-      break;
-   case TN_ROOT:
-      print_tree(path, tree->child);
-      break;
-   default:
-      Pmsg1(000, "Unknown node type %d\n", tree->type);
-   }
-   print_tree(path, tree->sibling);
-   return;
-}
 
 int tree_getpath(TREE_NODE *node, char *buf, int buf_size)
 {
@@ -565,4 +527,48 @@ void FillDirectoryTree(char *path, TREE_ROOT *root, TREE_NODE *parent)
    }
    closedir(dp);
 }
+
+#ifndef MAXPATHLEN
+#define MAXPATHLEN 2000
+#endif
+
+void print_tree(char *path, TREE_NODE *tree)
+{
+   char buf[MAXPATHLEN];
+   char *termchr;
+
+   if (!tree) {
+      return;
+   }
+   switch (tree->type) {
+   case TN_DIR_NLS:
+   case TN_DIR:
+   case TN_NEWDIR:  
+      termchr = "/";
+      break;
+   case TN_ROOT:
+   case TN_FILE:
+   default:
+      termchr = "";
+      break;
+   }
+   Dmsg3(-1, "%s/%s%s\n", path, tree->fname, termchr);
+   switch (tree->type) {
+   case TN_FILE:
+   case TN_NEWDIR:
+   case TN_DIR:
+   case TN_DIR_NLS:
+      bsnprintf(buf, sizeof(buf), "%s/%s", path, tree->fname);
+      print_tree(buf, tree->child);
+      break;
+   case TN_ROOT:
+      print_tree(path, tree->child);
+      break;
+   default:
+      Pmsg1(000, "Unknown node type %d\n", tree->type);
+   }
+   print_tree(path, tree->sibling);
+   return;
+}
+
 #endif
index e398e546cd361a417bca94dca576430e69545380..417669987178da27ba48db6ee8952a969c7be785 100644 (file)
  */
 
 struct s_mem {
-   struct s_mem *next;                /* next buffer */
-   int rem;                           /* remaining bytes */
-   char *mem;                         /* memory pointer */
-   char first[1];                     /* first byte */
+   struct s_mem *next;               /* next buffer */
+   int rem;                          /* remaining bytes */
+   char *mem;                        /* memory pointer */
+   char first[1];                    /* first byte */
 };
 
 /*
@@ -36,64 +36,62 @@ struct s_mem {
  *   there is one for each file.
  */
 struct s_tree_node {
-   char *fname;                       /* file name */
-   int32_t FileIndex;                 /* file index */
-   uint32_t JobId;                    /* JobId */
-   uint16_t fname_len;                /* filename length */
-   int type: 8;                       /* node type */
-   unsigned int extract: 1;           /* extract item */
+   char *fname;                      /* file name */
+   int32_t FileIndex;                /* file index */
+   uint32_t JobId;                   /* JobId */
+   uint16_t fname_len;               /* filename length */
+   int type: 8;                      /* node type */
+   unsigned int extract: 1;          /* extract item */
    unsigned int extract_dir: 1;       /* extract dir entry only */
-   unsigned int hard_link: 1;         /* set if have hard link */
-   unsigned int soft_link: 1;         /* set if is soft link */  
+   unsigned int hard_link: 1;        /* set if have hard link */
+   unsigned int soft_link: 1;        /* set if is soft link */  
    struct s_tree_node *parent;
    struct s_tree_node *sibling;
    struct s_tree_node *child;
-   struct s_tree_node *next;          /* next hash of FileIndex */
+   struct s_tree_node *next;         /* next hash of FileIndex */
 };
 typedef struct s_tree_node TREE_NODE;
 
 struct s_tree_root {
-   char *fname;                       /* file name */
-   int32_t FileIndex;                 /* file index */
-   uint32_t JobId;                    /* JobId */
-   uint16_t fname_len;                /* filename length */
-   unsigned int type: 8;              /* node type */
-   unsigned int extract: 1;           /* extract item */
+   char *fname;                      /* file name */
+   int32_t FileIndex;                /* file index */
+   uint32_t JobId;                   /* JobId */
+   uint16_t fname_len;               /* filename length */
+   unsigned int type: 8;             /* node type */
+   unsigned int extract: 1;          /* extract item */
    unsigned int extract_dir: 1;       /* extract dir entry only */
-   unsigned int have_link: 1;         /* set if have hard link */
+   unsigned int have_link: 1;        /* set if have hard link */
    struct s_tree_node *parent;
    struct s_tree_node *sibling;
    struct s_tree_node *child;
-   struct s_tree_node *next;          /* next hash of FileIndex */
+   struct s_tree_node *next;         /* next hash of FileIndex */
 
    /* The above ^^^ must be identical to a TREE_NODE structure */
-   struct s_tree_node *first;         /* first entry in the tree */
-   struct s_tree_node *last;          /* last entry in tree */
-   struct s_mem *mem;                 /* tree memory */
-   uint32_t total_size;               /* total bytes allocated */
-   uint32_t blocks;                   /* total mallocs */
-   int cached_path_len;               /* length of cached path */
-   char *cached_path;                 /* cached current path */
-   TREE_NODE *cached_parent;          /* cached parent for above path */
+   struct s_tree_node *first;        /* first entry in the tree */
+   struct s_tree_node *last;         /* last entry in tree */
+   struct s_mem *mem;                /* tree memory */
+   uint32_t total_size;              /* total bytes allocated */
+   uint32_t blocks;                  /* total mallocs */
+   int cached_path_len;              /* length of cached path */
+   char *cached_path;                /* cached current path */
+   TREE_NODE *cached_parent;         /* cached parent for above path */
 };
 typedef struct s_tree_root TREE_ROOT;
 
 /* type values */
-#define TN_ROOT    1                  /* root node */
-#define TN_NEWDIR  2                  /* created directory to fill path */
-#define TN_DIR     3                  /* directory entry */
-#define TN_DIR_NLS 4                  /* directory -- no leading slash -- win32 */
-#define TN_FILE    5                  /* file entry */
+#define TN_ROOT    1                 /* root node */
+#define TN_NEWDIR  2                 /* created directory to fill path */
+#define TN_DIR    3                  /* directory entry */
+#define TN_DIR_NLS 4                 /* directory -- no leading slash -- win32 */
+#define TN_FILE    5                 /* file entry */
 
 TREE_ROOT *new_tree(int count);
 TREE_NODE *new_tree_node(TREE_ROOT *root, int type);
 TREE_NODE *insert_tree_node(char *fname, TREE_NODE *node, 
-                            TREE_ROOT *root, TREE_NODE *parent);
+                           TREE_ROOT *root, TREE_NODE *parent);
 TREE_NODE *make_tree_path(char *path, TREE_ROOT *root);
 TREE_NODE *tree_cwd(char *path, TREE_ROOT *root, TREE_NODE *node);
 TREE_NODE *tree_relcwd(char *path, TREE_ROOT *root, TREE_NODE *node);
-void append_tree_node(char *path, TREE_NODE *node, TREE_ROOT *root, TREE_NODE *parent);
-void print_tree(char *path, TREE_NODE *root);    
 void free_tree(TREE_ROOT *root);
 int tree_getpath(TREE_NODE *node, char *buf, int buf_size);
 
index 6aa15024b9fdbae4ec032e2bbc46a3847a593da5..9ad4fd24839c0f981a2d4cbcf3e4e217b00aafda 100644 (file)
@@ -1,9 +1,9 @@
 /* */
 #undef  VERSION
-#define VERSION "1.33.5"
+#define VERSION "1.33.6"
 #define VSTRING "1"
-#define BDATE   "24 Mar 2004"
-#define LSMDATE "24Mar04"
+#define BDATE   "25 Mar 2004"
+#define LSMDATE "25Mar04"
 
 /* Debug flags */
 #undef  DEBUG