---
 yum/rpmsack.py |   50 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 50 insertions(+), 0 deletions(-)

diff --git a/yum/rpmsack.py b/yum/rpmsack.py
index 8e32fe0..6462d8e 100644
--- a/yum/rpmsack.py
+++ b/yum/rpmsack.py
@@ -1484,6 +1484,11 @@ class RPMDBAdditionalData(object):
         pass
 
 class RPMDBAdditionalDataPackage(object):
+
+    # We do auto hardlink on these attributes
+    _auto_hardlink_attrs = set(['from_repo', 'releasever', 'checksum_type',
+                                'installed_by', 'changed_by', 'reason'])
+
     def __init__(self, conf, pkgdir, yumdb_cache=None):
         self._conf = conf
         self._mydir = pkgdir
@@ -1497,6 +1502,41 @@ class RPMDBAdditionalDataPackage(object):
         # so we make it generic.
         self._yumdb_cache = yumdb_cache
 
+    def _auto_yumdb_cache(self, attr, value, fn, nlinks=1):
+        """ Create a cache for writting yumdb data out, to use link() instead 
of
+            open()+write(). hardlink -c works better, but this is "free" and
+            automatic. """
+        if self._yumdb_cache is None:
+            return
+        if nlinks <= 1 and attr not in self._auto_hardlink_attrs:
+            return
+
+        if attr not in self._yumdb_cache:
+            self._yumdb_cache[attr] = {}
+        if value in self._yumdb_cache[attr]:
+            if self._yumdb_cache[attr][value][0] >= nlinks:
+                # We already have a better cache file.
+                return
+
+        self._yumdb_cache[attr][value] = (nlinks, fn)
+
+    def _auto_link_yumdb_cache(self, attr, value, fn):
+        """ If we have a matching yumdb cache, link() to it instead of having
+            to open()+write(). """
+        if self._yumdb_cache is None:
+            return False
+        if attr not in self._yumdb_cache:
+            return False
+        if value not in self._yumdb_cache[attr]:
+            return False
+
+        misc.unlink_f(fn + '.tmp')
+        os.link(self._yumdb_cache[attr][value][1], fn + '.tmp')
+        os.rename(fn + '.tmp', fn)
+        self._read_cached_data[attr] = value
+
+        return True
+
     def _write(self, attr, value):
         # check for self._conf.writable before going on?
         if not os.path.exists(self._mydir):
@@ -1507,6 +1547,12 @@ class RPMDBAdditionalDataPackage(object):
             del self._read_cached_data[attr]
         fn = self._mydir + '/' + attr
         fn = os.path.normpath(fn)
+
+        # Auto hardlink some of the attrs...
+        if self._auto_link_yumdb_cache(attr, value, fn):
+            return
+
+        # Default write()+rename()... hardlink -c can still help.
         fo = open(fn + '.tmp', 'w')
         try:
             fo.write(value)
@@ -1518,6 +1564,8 @@ class RPMDBAdditionalDataPackage(object):
         del fo
         os.rename(fn +  '.tmp', fn) # even works on ext4 now!:o
         self._read_cached_data[attr] = value
+
+        self._auto_yumdb_cache(attr, value, fn)
     
     def _read(self, attr):
         attr = _sanitize(attr)
@@ -1546,6 +1594,8 @@ class RPMDBAdditionalDataPackage(object):
 
         if info.st_nlink > 1 and self._yumdb_cache is not None:
             self._yumdb_cache[key] = self._read_cached_data[attr]
+        self._auto_yumdb_cache(attr, self._read_cached_data[attr],
+                               fn, info.st_nlink)
 
         return self._read_cached_data[attr]
     
-- 
1.7.1.1

_______________________________________________
Yum-devel mailing list
Yum-devel@lists.baseurl.org
http://lists.baseurl.org/mailman/listinfo/yum-devel

Reply via email to