[Uludag-commits] r12250 - trunk/pisi/pisi

svn-uludag at uludag.org.tr svn-uludag at uludag.org.tr
5 Şub 2007 Pzt 16:51:05 EET


Author: faik
Date: Mon Feb  5 16:51:05 2007
New Revision: 12250

Modified:
   trunk/pisi/pisi/atomicoperations.py
   trunk/pisi/pisi/delta.py
Log:
* delta creation and delta package installation.
  
  The good part of this relocation implementation is that the 
  relocation info is calculated on-the-fly with no performance
  impact during the installation, so we do not need to find some
  somewhere to keep these.



Modified: trunk/pisi/pisi/atomicoperations.py
=================================================================
--- trunk/pisi/pisi/atomicoperations.py	(original)
+++ trunk/pisi/pisi/atomicoperations.py	Mon Feb  5 16:51:05 2007
@@ -286,6 +286,23 @@
                 os.rename(path, newconfig)
                 os.rename(oldconfig, path)
 
+        # Delta package does not contain the files that have the same hash as in 
+        # the old package's. Because it means the file has not changed. But some 
+        # of these files may be relocated to some other directory in the new package. 
+        # We handle these cases here.
+        def relocate_files():
+            from shutil import move
+            from pisi.delta import find_relocations
+            
+            relocations = find_relocations(self.old_files, self.files)
+
+            for old_file, new_file in relocations:
+                path = "/%s" % os.path.dirname(new_file.path)
+                if not os.path.exists(path):
+                    os.makedirs(path)
+
+                move("/%s" % old_file.path, "/%s" % new_file.path)                
+
         # remove left over files from the old package.
         def clean_leftovers():
             new = set(map(lambda x: str(x.path), self.files.list))
@@ -322,6 +339,9 @@
         if config_changed:
             rename_configs()
 
+        if self.package_fname.endswith(ctx.const.package_suffix):
+            relocate_files()
+
         if self.reinstall:
             clean_leftovers()
 

Modified: trunk/pisi/pisi/delta.py
=================================================================
--- trunk/pisi/pisi/delta.py	(original)
+++ trunk/pisi/pisi/delta.py	Mon Feb  5 16:51:05 2007
@@ -32,17 +32,16 @@
     oldfiles = oldpkg.get_files()
     newfiles = newpkg.get_files()
 
-    files_new = set(map(lambda x:(x.path, x.hash), newfiles.list))
-    files_old = set(map(lambda x:(x.path, x.hash), oldfiles.list))
-    files_delta = files_new - files_old
+    files_delta = find_delta(oldfiles, newfiles)
 
+    # FIXME: handle only metadata changed cases
     if not files_delta:
         ctx.ui.info(_("Nothing has changed between builds, not creating a delta"))
         return
 
     ctx.ui.info(_("Creating delta PiSi package between %s %s") % (old_package, new_package))
 
-    # Unpack new package to temp    
+    # Unpack new package to temp
     newpkg_name = util.package_name(newmd.package.name, newmd.package.version, newmd.package.release, newmd.package.build, False)
     newpkg_path = util.join_path(ctx.config.tmp_dir(), newpkg_name)
     newpkg.extract_to(newpkg_path, True)
@@ -57,7 +56,6 @@
     if outdir:
         deltaname = util.join_path(outdir, deltaname)
 
-    print deltaname
     deltapkg = Package(deltaname, "w")
 
     c = os.getcwd()
@@ -75,8 +73,8 @@
     ctx.build_leftover = util.join_path(ctx.config.tmp_dir(), ctx.const.install_tar_lzma)
 
     tar = archive.ArchiveTar(util.join_path(ctx.config.tmp_dir(), ctx.const.install_tar_lzma), "tarlzma")
-    for path, hash in files_delta:
-        tar.add_to_archive(path)
+    for file in files_delta:
+        tar.add_to_archive(file.path)
     tar.close()
 
     os.chdir(ctx.config.tmp_dir())
@@ -88,3 +86,40 @@
     os.chdir(c)
 
     ctx.ui.info(_("Done."))
+
+#  Hash not equals                      (these are the deltas)
+#  Hash equal but path different ones   (these are the relocations)
+#  Hash and also path equal ones        (do nothing)
+
+def find_delta(oldfiles, newfiles):
+
+    hashto_files = {}
+    for file in newfiles.list:
+        hashto_files[file.hash] = file
+
+    files_new = set(map(lambda x:x.hash, newfiles.list))
+    files_old = set(map(lambda x:x.hash, oldfiles.list))
+    files_delta = files_new - files_old
+
+    return map(lambda x:hashto_files[x], files_delta)
+
+def find_relocations(oldfiles, newfiles):
+
+# FIXME: A minor issue: Hash files may collide in any package (same file in different 
+# places in the same package.. ex. COPYING). Handle this case if check fails while installing. 
+# Because of that we do not use sets here but lists to append those files.
+
+    files_new = {}
+    for file in newfiles.list:
+        files_new.setdefault(file.hash, []).append(file)
+
+    files_old = {}
+    for file in oldfiles.list:
+        files_old.setdefault(file.hash, []).append(file)
+
+    relocations = []
+    for hash in files_new.keys():
+        if hash in files_old and files_new[hash][0].path != files_old[hash][0].path:
+            relocations.append((files_old[hash][0], files_new[hash][0]))
+
+    return relocations


Uludag-commits mesaj listesiyle ilgili daha fazla bilgi