gnu-arch-users
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Gnu-arch-users] patch: automatic cacherev and smarter get


From: Derek Zhou
Subject: [Gnu-arch-users] patch: automatic cacherev and smarter get
Date: Tue, 22 Nov 2005 13:49:18 -0800

This patch implements the following:
* automatic cachrev every 50 commits
* smarter get algorithm. Now it weights between several possible
ways to get a revision and use the one that take the minimum effort
Caveats:
* the number 50 is hard coded; it really should be a value that the user
can customize.
* when there is a greedy and non-sparse revlib and it doesn't contain
anything, tla still go all the way back. (maybe we should limit the number
of recursions in non-sparse revlib)
The patch overhauls the build-revision.c and changes half of the
library-txn.c. Still need more testing.

Derek

* looking for address@hidden/tla--derek-no-pristines--1.3--base-0 to compare 
with
* comparing to address@hidden/tla--derek-no-pristines--1.3--base-0
M  libarch/library-txn.c
M  libarch/cmd-get.c
M  libarch/cmd-commit.c
M  libarch/build-revision.h
M  libarch/arch.h
M  libarch/build-revision.c

* modified files

--- orig/libarch/arch.h
+++ mod/libarch/arch.h
@@ -14,6 +14,7 @@
 #include "hackerlab/char/char-class.h"
 
 
+#define arch_default_cachrev_penalty 50
 
 static const int arch_escape_classes = char_class_control | char_class_space | 
char_class_non_ascii;
 


--- orig/libarch/build-revision.c
+++ mod/libarch/build-revision.c
@@ -18,9 +18,11 @@
 #include "tla/libfsutils/dir-listing.h"
 #include "tla/libfsutils/tmp-files.h"
 #include "tla/libfsutils/rmrf.h"
+#include "tla/libfsutils/same.h"
 #include "tla/libarch/namespace.h"
 #include "tla/libarch/libraries.h"
 #include "tla/libarch/archive.h"
+#include "tla/libarch/arch.h"
 #include "tla/libarch/apply-changeset.h"
 #include "tla/libarch/project-tree.h"
 #include "tla/libarch/pristines.h"
@@ -30,78 +32,165 @@
 #include "tla/libarch/build-revision.h"
 
 
+/* build the rev from a lib. return 1 if built 0 otherwise */
+static int
+build_from_lib (const t_uchar * dest_dir,
+                const t_uchar * archive,
+                const t_uchar * revision, 
+                int hardlinks)
+{
+  t_uchar * library_rev_dir = arch_library_find (rel_table_nil, archive, 
revision, 1);
+  rel_table index_by_name = rel_table_nil;
+  int full_meta;
+  if (library_rev_dir) 
+    {
+      full_meta = arch_tree_has_meta_flag (library_rev_dir);
+      index_by_name = arch_library_index (archive, revision);
+      rel_sort_table_by_field (0, index_by_name, 0);
+      if (hardlinks && on_same_device (library_rev_dir, dest_dir))   // try 
hardlink
+        {
+          rmrf_file (dest_dir);             // otherwise will fail
+          build_partial_link_tree (library_rev_dir, dest_dir, index_by_name, 
full_meta);
+        }
+      else
+        copy_file_list (dest_dir, library_rev_dir, index_by_name, full_meta);
+      rel_free_table (index_by_name);
+      lim_free (0, library_rev_dir);
+      return 1;
+    }
+  return 0;
+}
+                
+/* build the rev from a pristine cache. return 1 if built 0 otherwise */
+static int
+build_from_cache (const t_uchar * dest_dir,
+                  const t_uchar * archive,
+                  const t_uchar * revision, 
+                  const t_uchar * cache_dir)
+{
+  t_uchar * pristine_copy = 0;
+  
+  if (cache_dir)
+    {
+      pristine_copy = arch_find_pristine (0, cache_dir, archive, revision, 
arch_any_pristine, 
+                                          arch_cache_dir_pristine_search);
+      if (pristine_copy)
+        {
+          rel_table file_list = rel_table_nil;
+          int full_meta = arch_tree_has_meta_flag (pristine_copy);
+          
+          file_list = arch_source_inventory (pristine_copy, 1, 0, 0);
+          copy_file_list (dest_dir, pristine_copy, file_list, full_meta);
 
+          rel_free_table (file_list);
+          lim_free (0, pristine_copy);
+          return 1;
+        }
+    }
+  return 0;
+}
+                
+static void 
+build_from_dir (const t_uchar * dest_dir,
+                const t_uchar * src_dir)
+{
+  rel_table files = rel_table_nil;
+  int x;
+  
+  files = directory_files (src_dir);
+  
+  for (x = 0; x < rel_n_records (files); ++x)
+    {
+      if (str_cmp (".", rel_peek_str (files, x, 0)) && str_cmp ("..", 
rel_peek_str (files, x, 0)))
+        {
+          t_uchar * frm = 0;
+          t_uchar * to = 0;
+          
+          frm = file_name_in_vicinity (0, src_dir, rel_peek_str (files, x, 0));
+          to = file_name_in_vicinity (0, dest_dir, rel_peek_str (files, x, 0));
+          
+          safe_rename (frm, to);
+          
+          lim_free (0, frm);
+          lim_free (0, to);
+        }
+    }
+  rel_free_table (files);
+}
+                  
+static void
+patch_to_current_revision (const t_uchar * dest_dir,
+                           struct arch_archive * arch,
+                           const t_uchar * revision, 
+                           int escape_classes)
+{
+  t_uchar * tmppatch = 0;
+  struct arch_apply_changeset_report r;
+  
+  tmppatch = tmp_file_name (dest_dir, ",,next-patch");
+  arch_get_patch (arch, revision, tmppatch);
+  
+  mem_set0 ((t_uchar *)&r, sizeof (r));
+  
+  arch_apply_changeset (&r, tmppatch, dest_dir, arch_unspecified_id_tagging, 
+                        arch_inventory_unrecognized, 0, 0, 0, 0, 0, 
escape_classes);
+  
+  if (arch_conflicts_occured (&r))
+    panic ("conflict applying patch in arch_build_revision");
+  
+  arch_free_apply_changeset_report_data (&r);
+  
+  rmrf_file (tmppatch);
+  lim_free (0, tmppatch);
+}
 
-/* return non-0 if it came from a library.
+/* build the revision if can be done with effort less than limit - 
starting_effort
+ * the effort is defined as:
+ * - building with local (library copy) tree takes 0;
+ * - building with a patch takes +1;
+ * - building with a cacherev or import takes 
arch_build_arch_default_cachrev_penalty
+ * return 1 if built from library, 2 if built but not from a library, 0 if not 
built
  */
 int
-arch_build_revision (int chatter_fd,
-                     const t_uchar * dest_dir,
-                     struct arch_archive * arch,
-                     const t_uchar * archive,
-                     const t_uchar * revision,
-                     const t_uchar * cache_dir)
+arch_build_revision_rec (int chatter_fd,
+                         const t_uchar * dest_dir,
+                         struct arch_archive * arch,
+                         const t_uchar * archive,
+                         const t_uchar * revision,
+                         const t_uchar * cache_dir, 
+                         int hardlinks, 
+                         int escape_classes, 
+                         int limit, 
+                         int starting_effort)
 {
-  struct arch_archive * my_arch = 0;
-  t_uchar * library_rev_dir = 0;
-  int is_built = 0;
-  int from_library = 0;
-
-  library_rev_dir = arch_library_find (rel_table_nil, archive, revision, 1);
+  int answer = 0;
 
   /****************************************************************
    * Take it from a revision library, if we can.
    */
-  if (!is_built && library_rev_dir)
+  if (build_from_lib(dest_dir, archive, revision, hardlinks))
     {
-      rel_table index_by_name = rel_table_nil;
-      const int full_meta = arch_tree_has_meta_flag (library_rev_dir);
-
       arch_chatter (chatter_fd, "* from revision library: %s/%s\n", archive, 
revision);
-
-      index_by_name = arch_library_index (archive, revision);
-      rel_sort_table_by_field (0, index_by_name, 0);
-      copy_file_list (dest_dir, library_rev_dir, index_by_name, full_meta);
-
-      rel_free_table (index_by_name);
-
-      is_built = 1;
-      from_library = 1;
+      answer = 1;
     }
 
   /****************************************************************
    * Next, try the pristine cache.
    */
-  if (!is_built && cache_dir)
+  else if (build_from_cache(dest_dir, archive, revision, cache_dir))
     {
-      t_uchar * pristine_copy = 0;
-
-      pristine_copy = arch_find_pristine (0, cache_dir, archive, revision, 
arch_any_pristine, arch_cache_dir_pristine_search);
-
-      if (pristine_copy)
-        {
-          rel_table file_list = rel_table_nil;
-          const int full_meta = arch_tree_has_meta_flag (pristine_copy);
-
-          arch_chatter (chatter_fd, "* from pristine cache: %s/%s\n", archive, 
revision);
-
-          file_list = arch_source_inventory (pristine_copy, 1, 0, 0);
-          copy_file_list (dest_dir, pristine_copy, file_list, full_meta);
-          is_built = 1;
-
-          rel_free_table (file_list);
-        }
-
-      lim_free (0, pristine_copy);
+      arch_chatter (chatter_fd, "* from pristine cache: %s/%s\n", archive, 
revision);
+      answer = 2;
     }
 
   /****************************************************************
    * Ok, have to hit up the archive.
    */
-  if (!is_built)
+  else
     {
       enum arch_revision_type type;
       int is_cached;
+      struct arch_archive * my_arch = 0;
 
       if (!arch)
         {
@@ -112,166 +201,133 @@
       arch_revision_type (&type, &is_cached, arch, revision);
 
       /********************************
-       * Archive Cached Revision?
-       */
-      if (is_cached)
-        {
-          t_uchar * tmpdir = 0;
-          rel_table files = rel_table_nil;
-          int x;
-
-          arch_chatter (chatter_fd, "* from archive cached: %s/%s\n", archive, 
revision);
-
-          tmpdir = tmp_file_name (dest_dir, ",,cached-revision");
-          arch_get_cached_revision (arch, revision, tmpdir);
-          files = directory_files (tmpdir);
-
-          for (x = 0; x < rel_n_records (files); ++x)
-            {
-              if (str_cmp (".", rel_peek_str (files, x, 0)) && str_cmp ("..", 
rel_peek_str (files, x, 0)))
-                {
-                  t_uchar * frm = 0;
-                  t_uchar * to = 0;
-
-                  frm = file_name_in_vicinity (0, tmpdir, rel_peek_str (files, 
x, 0));
-                  to = file_name_in_vicinity (0, dest_dir, rel_peek_str 
(files, x, 0));
-
-                  safe_rename (frm, to);
-
-                  lim_free (0, frm);
-                  lim_free (0, to);
-                }
-            }
-
-          safe_rmdir (tmpdir);
-
-          lim_free (0, tmpdir);
-          rel_free_table (files);
-        }
-
-      /********************************
        * Import Revision?
        */
-      else if (type == arch_import_revision)
+      if (type == arch_import_revision)
         {
-          t_uchar * tmpdir = 0;
-          rel_table files = rel_table_nil;
-          int x;
-
-          arch_chatter (chatter_fd, "* from import revision: %s/%s\n", 
archive, revision);
-
-          tmpdir = tmp_file_name (dest_dir, ",,import-revision");
-          arch_get_import_revision (arch, revision, tmpdir);
-          files = directory_files (tmpdir);
-
-          for (x = 0; x < rel_n_records (files); ++x)
+          int new_limit = starting_effort + arch_default_cachrev_penalty;
+          if ((limit==-1) || (new_limit < limit))    // build here
             {
-              if (str_cmp (".", rel_peek_str (files, x, 0)) && str_cmp ("..", 
rel_peek_str (files, x, 0)))
-                {
-                  t_uchar * frm = 0;
-                  t_uchar * to = 0;
-
-                  frm = file_name_in_vicinity (0, tmpdir, rel_peek_str (files, 
x, 0));
-                  to = file_name_in_vicinity (0, dest_dir, rel_peek_str 
(files, x, 0));
-
-                  safe_rename (frm, to);
-
-                  lim_free (0, frm);
-                  lim_free (0, to);
-                }
+              t_uchar * tmpdir = 0;
+              arch_chatter (chatter_fd, "* from import revision: %s/%s\n", 
archive, revision);
+              tmpdir = tmp_file_name (dest_dir, ",,import-revision");
+              arch_get_import_revision (arch, revision, tmpdir);
+              build_from_dir(dest_dir, tmpdir);
+              safe_rmdir (tmpdir);
+              lim_free (0, tmpdir);
+              answer = 2;
             }
-
-          safe_rmdir (tmpdir);
-
-          lim_free (0, tmpdir);
-          rel_free_table (files);
         }
       else
         {
+          int new_limit = limit;
           /********************************
-           * Recurse and Build by Patching
+           * Archive Cached Revision?
            */
-
-          t_uchar * prev_revision = 0;
-          t_uchar * prev_archive = 0;
-          struct arch_archive * prev_arch;
-
-          if (type == arch_simple_revision)
+          if (is_cached)
             {
-              prev_revision = arch_previous_revision (arch, revision);
-              invariant (!!prev_revision);
-              prev_archive = str_save (0, archive);
-              prev_arch = arch;
+              new_limit = starting_effort + arch_default_cachrev_penalty;
+              if ((limit!=-1) && (new_limit >= limit))    // too much effort 
to build here
+                new_limit = limit;
             }
-          else
+          if (new_limit==-1 || new_limit > starting_effort+1)     // ok to 
search more
             {
-              t_uchar * fq_prev_revision = 0;
-
-              fq_prev_revision = arch_get_continuation (arch, revision);
-
-              if (!arch_valid_package_name (fq_prev_revision, 
arch_req_archive, arch_req_patch_level, 0))
-                {
-                  safe_printfmt (2, "arch_build_revision: archive contains 
bogus CONTINUATION file\n  archive: %s\n  revision: %s\n",
-                                 archive, revision);
-                  exit (2);
-                }
-
-              prev_archive = arch_parse_package_name (arch_ret_archive, 0, 
fq_prev_revision);
-              prev_revision = arch_parse_package_name (arch_ret_non_archive, 
0, fq_prev_revision);
-
-              if (!str_cmp (archive, prev_revision))
+              /********************************
+               * find previous revision
+               */
+              t_uchar * prev_revision = 0;
+              t_uchar * prev_archive = 0;
+              struct arch_archive * prev_arch;
+              
+              if (type == arch_simple_revision)
                 {
+                  prev_revision = arch_previous_revision (arch, revision);
+                  invariant (!!prev_revision);
+                  prev_archive = str_save (0, archive);
                   prev_arch = arch;
                 }
               else
                 {
-                  prev_arch = arch_archive_connect (prev_archive, 0);
+                  t_uchar * fq_prev_revision = 0;
+                  
+                  fq_prev_revision = arch_get_continuation (arch, revision);
+                  if (!arch_valid_package_name (fq_prev_revision, 
arch_req_archive, 
+                                                arch_req_patch_level, 0))
+                    {
+                      safe_printfmt (2, "arch_build_revision: archive contains 
bogus CONTINUATION file\n  archive: %s\n  revision: %s\n",
+                                     archive, revision);
+                      exit (2);
+                    }
+
+                  prev_archive = arch_parse_package_name (arch_ret_archive, 0, 
fq_prev_revision);
+                  prev_revision = arch_parse_package_name 
(arch_ret_non_archive, 0, fq_prev_revision);
+                  lim_free (0, fq_prev_revision);
+                  if (!str_cmp (archive, prev_archive))
+                    prev_arch = arch;
+                  else if (new_limit == -1)           // no solution yet
+                    prev_arch = arch_archive_connect (prev_archive, 0);
+                  else           // we do not cross archive boundary unless 
neccessary 
+                    prev_arch = 0;
                 }
+              if (prev_arch)
+                answer = arch_build_revision_rec (chatter_fd, dest_dir, 
prev_arch, prev_archive, 
+                                                  prev_revision, cache_dir, 
hardlinks, escape_classes, 
+                                                  new_limit, 
starting_effort+1);
+              
+              lim_free (0, prev_archive);
+              lim_free (0, prev_revision);
+              if (arch != prev_arch)
+                arch_archive_close (prev_arch);
 
-              lim_free (0, fq_prev_revision);
+              if (answer!=0)
+                {
+                  arch_chatter (chatter_fd, "* patching for the revision: 
%s/%s\n", archive, revision);
+                  patch_to_current_revision(dest_dir, arch, revision, 
escape_classes);
+                  answer = 2;
+                }
+            }
+          if (answer==0 && is_cached && new_limit!=limit) // build here
+            {
+              t_uchar * tmpdir = 0;
+              arch_chatter (chatter_fd, "* from archive cached: %s/%s\n", 
archive, revision);
+              tmpdir = tmp_file_name (dest_dir, ",,cached-revision");
+              arch_get_cached_revision (arch, revision, tmpdir);
+              build_from_dir(dest_dir, tmpdir);
+              safe_rmdir (tmpdir);
+              lim_free (0, tmpdir);
+              answer = 2;
             }
-
-
-          arch_build_revision (chatter_fd, dest_dir, prev_arch, prev_archive, 
prev_revision, cache_dir);
-
-          arch_chatter (chatter_fd, "* patching for revision: %s/%s\n", 
archive, revision);
-
-          {
-            t_uchar * tmppatch = 0;
-            struct arch_apply_changeset_report r;
-
-            tmppatch = tmp_file_name (dest_dir, ",,next-patch");
-            arch_get_patch (arch, revision, tmppatch);
-
-            mem_set0 ((t_uchar *)&r, sizeof (r));
-
-            arch_apply_changeset (&r, tmppatch, dest_dir, 
arch_unspecified_id_tagging, arch_inventory_unrecognized, 0, 0, 0, 0, 0, 0);
-
-            if (arch_conflicts_occured (&r))
-              panic ("conflict applying patch in arch_build_revision");
-
-            arch_free_apply_changeset_report_data (&r);
-
-            rmrf_file (tmppatch);
-            lim_free (0, tmppatch);
-          }
-
-          if (arch != prev_arch)
-            arch_archive_close (prev_arch);
-
-          lim_free (0, prev_archive);
-          lim_free (0, prev_revision);
         }
+      arch_archive_close (my_arch);
     }
 
-  arch_snap_inode_sig (dest_dir, archive, revision);
+  if (answer!=0)  // built
+    arch_snap_inode_sig (dest_dir, archive, revision);
 
-  lim_free (0, library_rev_dir);
-  arch_archive_close (my_arch);
-  return from_library;
+  return answer;
 }
 
-
+/* return non-0 if it came from a library.
+ */
+int
+arch_build_revision (int chatter_fd,
+                     const t_uchar * dest_dir,
+                     struct arch_archive * arch,
+                     const t_uchar * archive,
+                     const t_uchar * revision,
+                     const t_uchar * cache_dir)
+{
+  int answer = arch_build_revision_rec(chatter_fd, dest_dir, arch, archive, 
+                                  revision, cache_dir, 0, 0, 
+                                  -1, 0);
+  if (answer==0) 
+    {
+      safe_printfmt (2, "arch_build_revision: fail to build: archive: %s\n  
revision: %s\n",
+                     archive, revision);
+      exit (2);
+    }
+  return answer==2 ? 0 : 1;
+}
 
 
 


--- orig/libarch/build-revision.h
+++ mod/libarch/build-revision.h
@@ -13,9 +13,19 @@
 
 #include "tla/libarch/archive.h"
 
-
 
 /* automatically generated __STDC__ prototypes */
+extern int arch_build_revision_rec (int chatter_fd,
+                                    const t_uchar * dest_dir,
+                                    struct arch_archive * arch,
+                                    const t_uchar * archive,
+                                    const t_uchar * revision,
+                                    const t_uchar * cache_dir, 
+                                    int hardlinks, 
+                                    int escape_classes, 
+                                    int limit, 
+                                    int starting_effort);
+
 extern int arch_build_revision (int chatter_fd,
                                 const t_uchar * dest_dir,
                                 struct arch_archive * arch,


--- orig/libarch/cmd-commit.c
+++ mod/libarch/cmd-commit.c
@@ -20,6 +20,7 @@
 #include "tla/libarch/cmd.h"
 #include "tla/libarch/editor.h"
 #include "tla/libarch/cmd-commit.h"
+#include "tla/libarch/archive-cache.h"
 
 
 /* __STDC__ prototypes for static functions */
@@ -61,6 +62,8 @@
       "log with TEXT plus log-for-merge output") \
   OP (opt_strict, 0, "strict", 0, \
       "strict tree-lint") \
+  OP (opt_no_cacherev, 0, "no-cacherev", 0, \
+      "Disable automatic cacherev") \
   OP (opt_seal, 0, "seal", 0, \
       "create a version-0 revision") \
   OP (opt_fix, 0, "fix", 0, \
@@ -111,6 +114,8 @@
   int strict = 0;
   int seal = 0;
   int fix = 0;
+  int no_cacherev = 0;
+  int cacherev = 0;
   int out_of_date_ok = 0;
   t_uchar * file_list_file = 0;
   int opt_end_with_double_dash = 0;
@@ -187,6 +192,12 @@
             break;
           }
 
+        case opt_no_cacherev:
+          {
+            no_cacherev = 1;
+            break;
+          }
+
         case opt_strict:
           {
             strict = 1;
@@ -434,6 +445,8 @@
             {
               desired_level_type = arch_is_patch_level;
               desired_n = last_n + 1;
+              if (!no_cacherev)
+                cacherev = ((desired_n % arch_default_cachrev_penalty) == 0) ? 
1 : 0;
             }
           break;
         }
@@ -505,6 +518,15 @@
 
     arch_commit (1, arch, revision, tree_root, log, file_list, escape_classes);
 
+    if ( cacherev)
+      {
+        safe_printfmt (1, "* Archive caching revision\n");
+        safe_flush (1);
+
+        arch_archive_cache (1, arch, archive, revision, tree_root);
+        safe_printfmt (1, "* Made cached revision of  %s/%s \n", archive, 
revision);
+      }
+
     safe_printfmt (1, "* committed %s/%s\n", archive, revision);
 
     if (log_file)


--- orig/libarch/cmd-get.c
+++ mod/libarch/cmd-get.c
@@ -159,13 +159,11 @@
         case opt_hardlinks:
           {
             hardlinks = 1;
-            no_pristine = 1;
             break;
           }
 
         case opt_library:
           {
-            no_pristine = 1;
             library = 1;
             break;
           }
@@ -223,6 +221,7 @@
     t_uchar * tmp_dir = 0;
     t_uchar *opt_same_dev_path = 0; 
     struct arch_archive * arch = 0;
+    int answer;
 
     here_fd = safe_open (".", O_RDONLY, 0);
 
@@ -343,7 +342,7 @@
     tmp_dir = tmp_file_name (output_dir_dir, tmp_tail);
 
     rmrf_file (tmp_dir);
-
+    
     if (!library && permit_greed)
       {
         /* Prefer a library entry over making a pristine tree, if there's
@@ -368,39 +367,29 @@
 
        arch_library_add (1, 1, arch, revision, selected_library, 
opt_same_dev_path, sparse, escape_classes);
       }
-
+    
     /* make hardlinks or build-revision
      */
     if (hardlinks)
       {
-        t_uchar * revision_dir = 0;
-        rel_table index = rel_table_nil;
-        int full_meta;
-
-        index = arch_library_index (archive, revision);
-        rel_sort_table_by_field (0, index, 0);
-
         safe_printfmt (1, "* hard linking to library\n");
         safe_flush (1);
-
-        revision_dir = arch_library_find (rel_table_nil, archive, revision, 1);
-        invariant (0 != revision_dir);
-        full_meta = arch_tree_has_meta_flag (revision_dir);
-        
-        build_partial_link_tree (arch_library_find (rel_table_nil, archive, 
revision, 1), tmp_dir, index, full_meta);
-        arch_snap_inode_sig (tmp_dir, archive, revision);
-
-        lim_free (0, revision_dir);
       }
-    else
+
+    safe_mkdir (tmp_dir, 0777);
+    answer = arch_build_revision_rec ((silent ? -1 : 1), tmp_dir, 
+                                      arch, archive, revision, cache_dir, 
+                                      hardlinks, 0, -1, 0);
+    if (answer==0) 
       {
-        safe_mkdir (tmp_dir, 0777);
-        no_pristine = arch_build_revision ((silent ? -1 : 1), tmp_dir, arch, 
archive, revision, cache_dir);
+        safe_printfmt (2, "%s: fail to get: archive: %s\n  revision: %s\n",
+                       argv[0], archive, revision);
+        exit (2);
       }
 
     arch_archive_close (arch);
 
-    if (!no_pristine)
+    if (!no_pristine && answer==2)    // not from a library and no_pristine==0
       {
         if (!silent)
           {


--- orig/libarch/library-txn.c
+++ mod/libarch/library-txn.c
@@ -375,189 +375,36 @@
   ensure_directory_exists (dest_dir_dir);
   tmp_dir = tmp_file_name (dest_dir_dir, ",,new-revision");
 
-  if (library_ancestor)
+  /* There is an ancestor, it's in the same archive, it's not 
+   * in the library, and we're not building a --sparse library.
+   * So, recursively add the ancestor to the library and then
+   * build it
+   */
+  if (!library_ancestor && fq_ancestor_rev && 
+      !str_cmp (ancestor_archive, arch->name) && !sparse) 
     {
-      const int full_meta = arch_tree_has_meta_flag (library_ancestor);
-
-      /* If the immediate ancestor exists in the same library,
-       * then fill our tmp dir with a link-tree to that ancestor.
-       * It will be patched for our target revision later.
-       */
-
-      arch_chatter (chatter_fd, "* found immediate ancestor revision in 
library (%s/%s)\n", ancestor_archive, ancestor_revision);
-      build_link_tree (library_ancestor, tmp_dir, full_meta);
+      arch_chatter (chatter_fd, "* recursively adding %s/%s to library\n", 
ancestor_archive, ancestor_revision);
+      arch_library_add (chatter_fd, no_patch_noise, arch, ancestor_revision, 
opt_library, opt_same_dev_path, 0, escape_classes);
     }
-  else if (!fq_ancestor_rev || str_cmp (ancestor_archive, arch->name))
-    {
-      /* If there is no immediate ancestor (we're trying to build 
-       * an import revision) or if the ancestor is in some other archive,
-       * fill the tmp-dir with the target revision just by building
-       * it from scratch.
-       * 
-       * There's no need to further patch the tmp-dir after that.
-       */
-
-      safe_mkdir (tmp_dir, 0777);
-      arch_build_revision (chatter_fd, tmp_dir, arch, arch->name, revision, 0);
-
-      patch_set_dir = file_name_in_vicinity (0, tmp_dir, ",,patch-set");
-      rmrf_file (patch_set_dir);
-
-      if (fq_ancestor_rev)
-        {
-          arch_get_patch (arch, revision, patch_set_dir);
-        }
-      else
-        {
-          safe_mkdir (patch_set_dir, 0777);
-        }
 
-      goto no_need_to_patch;
-    }
-  else if (!sparse)
+  /* Build the current version with hardlink if possible */
+  safe_mkdir (tmp_dir, 0777);
+  arch_build_revision_rec (chatter_fd, tmp_dir, 
+                           arch, arch->name, revision, 0, 
+                           1, escape_classes, -1, 0);
+  
+  patch_set_dir = file_name_in_vicinity (0, tmp_dir, ",,patch-set");
+  rmrf_file (patch_set_dir);
+      
+  if (fq_ancestor_rev)
     {
-      const int full_meta = arch_tree_has_meta_flag (library_ancestor);
-
-      /* There is an ancestor, it's in the same archive, it's not 
-       * in the library, and we're not building a --sparse library.
-       * So, recursively add the ancestor to the library and then
-       * build a link-tree into tmp-dir.   We'll patch tmp-dir to the
-       * target revision later.
-       */
-      arch_chatter (chatter_fd, "* recursively adding %s/%s to library\n", 
ancestor_archive, ancestor_revision);
-      arch_library_add (chatter_fd, no_patch_noise, arch, ancestor_revision, 
opt_library, opt_same_dev_path, 0, escape_classes);
-      library_ancestor = arch_library_find (rel_table_nil, ancestor_archive, 
ancestor_revision, 1);
-      build_link_tree (library_ancestor, tmp_dir, full_meta);
+      arch_get_patch (arch, revision, patch_set_dir);
     }
   else
     {
-      /* There is an ancestor, it's in the same archive, it's
-       * not in the library, but we're building a --sparse library.
-       *
-       * If some _earlier_ ancestor is at hand, link to that and then
-       * patch.   Otherwise, build the target revision from scratch.
-       * 
-       * Either way, at the end, tmp-dir will have the target revision
-       * and there's no need to further patch it.
-       */
-      t_uchar * anc_arch = str_save (0, ancestor_archive);
-      t_uchar * anc_rev = str_save (0, ancestor_revision);
-      t_uchar * anc_lib = 0;
-      int replay_status = 1;
-      /* list of patches to apply to revision in library to achieve new 
revision
-       */
-      rel_table revisions = rel_table_nil;
-
-      /* this is the first patch missing
-       */
-      rel_add_records (&revisions,  rel_singleton_record_taking 
(rel_make_field_str (revision)), rel_record_null);
-
-      arch_chatter (chatter_fd, "* searching ancestor revision in library in 
archive %s\n", ancestor_archive);
-
-      /* search backwards in the library for a revision to link to
-       */
-      while (anc_rev && !anc_lib)
-        {
-          t_uchar * fq_anc_rev = 0;
-          t_uchar * prev_rev = 0;
-
-          /* add revision to list
-           */
-
-          rel_add_records (&revisions,  rel_singleton_record_taking 
(rel_make_field_str (anc_rev)), rel_record_null);
-
-          /* look in the library for the immediate ancestor
-           */
-          fq_anc_rev = arch_ancestor_revision (arch, anc_rev);
-
-          if (fq_anc_rev)
-            {
-              lim_free (0, anc_arch);
-              lim_free (0, anc_rev);
-
-              anc_arch = arch_parse_package_name (arch_ret_archive, 0, 
fq_anc_rev);
-              anc_rev = arch_parse_package_name (arch_ret_non_archive, 0, 
fq_anc_rev);
-              anc_lib = arch_library_find (rel_table_nil, anc_arch, anc_rev, 
1);
-            }
-
-          if (!fq_anc_rev || str_cmp (anc_arch, arch->name))
-            {
-              /* no ancestor in the same archive
-               */
-              arch_chatter (chatter_fd, "* no ancestor in library for revision 
%s/%s in the same archive\n", anc_arch, revision);
-              lim_free (0, fq_anc_rev);
-              lim_free (0, prev_rev);
-              break;
-            }
-
-          lim_free (0, fq_anc_rev);
-          lim_free (0, prev_rev);
-        }
-
-      /* let's patch the found revision in the library up to the needed 
revision
-       */
-      if (anc_lib)
-        {
-          const int full_meta = arch_tree_has_meta_flag (anc_lib);
-          arch_chatter (chatter_fd, "* found ancestor revision in library 
(%s/%s)\n", anc_arch, anc_rev);
-          arch_chatter (chatter_fd, "* patching for this revision (%s/%s)\n", 
ancestor_archive, revision);
-          build_link_tree (anc_lib, tmp_dir, full_meta);
-          rel_reverse_table (revisions);
-          replay_status = arch_replay_list (chatter_fd, 1, tmp_dir, arch, 
revisions, 0, 0, escape_classes);
-          invariant (!replay_status);
-          lim_free (0, anc_lib);
-        }
-      else
-        {
-          /* otherwise (1st revision in library) build the revision from 
scratch
-           */
-          safe_mkdir (tmp_dir, 0777);
-          arch_build_revision (chatter_fd, tmp_dir, arch, arch->name, 
revision, 0);
-        }
-
-      /* keep last patchset inside revision
-       */
-      patch_set_dir = file_name_in_vicinity (0, tmp_dir, ",,patch-set");
-      rmrf_file (patch_set_dir);
-      arch_get_patch (arch, revision, patch_set_dir);
-
-      lim_free (0, anc_arch);
-      lim_free (0, anc_rev);
-      rel_free_table (revisions);
-      goto no_need_to_patch;
+      safe_mkdir (patch_set_dir, 0777);
     }
 
-
-  /* This is reached only if we have one-last patch to make to 
-   * tmp-dir to achieve the target revision.
-   * 
-   * If tmp-dir already has the target, then we `goto no_need_to_patch',
-   * below.
-   */
-
-  patch_set_dir = file_name_in_vicinity (0, tmp_dir, ",,patch-set");
-  rmrf_file (patch_set_dir);
-  arch_get_patch (arch, revision, patch_set_dir);
-
-  {
-    struct arch_apply_changeset_report report = {0,};
-
-    arch_chatter (chatter_fd, "* patching for this revision (%s/%s)\n", 
arch->name, revision);
-
-    if ((chatter_fd >= 0) && !no_patch_noise)
-      {
-        report.callback = library_txn_callback;
-        report.thunk = (void *)(long)chatter_fd;
-      }
-
-    arch_apply_changeset (&report, patch_set_dir, tmp_dir, 
arch_unspecified_id_tagging, arch_inventory_unrecognized, 0, 0, 0, 0, 0, 
escape_classes);
-    invariant (!arch_conflicts_occured (&report));
-
-    arch_free_apply_changeset_report_data (&report);
-  }
-
- no_need_to_patch:
-
   /* Finish up adding ancillary files to the tmp-dir and then
    * install it in the library.
    */







reply via email to

[Prev in Thread] Current Thread [Next in Thread]