]> arthur.barton.de Git - bup.git/blobdiff - lib/bup/index.py
Merge remote branch 'origin/master' into meta
[bup.git] / lib / bup / index.py
index 348b73d8ea45a1ce16ff973161a8edd19cd4fcc2..c000fbb9ce1757728b339452eb72543494b5d543 100644 (file)
@@ -95,17 +95,19 @@ class Entry:
     def from_stat(self, st, tstart):
         old = (self.dev, self.ctime, self.mtime,
                self.uid, self.gid, self.size, self.flags & IX_EXISTS)
-        new = (st.st_dev, int(st.st_ctime), int(st.st_mtime),
+        new = (st.st_dev,
+               int(st.st_ctime.approx_secs()),
+               int(st.st_mtime.approx_secs()),
                st.st_uid, st.st_gid, st.st_size, IX_EXISTS)
         self.dev = st.st_dev
-        self.ctime = int(st.st_ctime)
-        self.mtime = int(st.st_mtime)
+        self.ctime = int(st.st_ctime.approx_secs())
+        self.mtime = int(st.st_mtime.approx_secs())
         self.uid = st.st_uid
         self.gid = st.st_gid
         self.size = st.st_size
         self.mode = st.st_mode
         self.flags |= IX_EXISTS
-        if int(st.st_ctime) >= tstart or old != new \
+        if int(st.st_ctime.approx_secs()) >= tstart or old != new \
               or self.sha == EMPTY_SHA or not self.gitmode:
             self.invalidate()
         self._fixup()
@@ -160,9 +162,9 @@ class Entry:
         return not self.ctime
 
     def __cmp__(a, b):
-        return (cmp(a.name, b.name)
-                or -cmp(a.is_valid(), b.is_valid())
-                or -cmp(a.is_fake(), b.is_fake()))
+        return (cmp(b.name, a.name)
+                or cmp(a.is_valid(), b.is_valid())
+                or cmp(a.is_fake(), b.is_fake()))
 
     def write(self, f):
         f.write(self.basename + '\0' + self.packed())
@@ -406,8 +408,10 @@ class Writer:
         if st:
             isdir = stat.S_ISDIR(st.st_mode)
             assert(isdir == endswith)
-            e = NewEntry(basename, name, st.st_dev, int(st.st_ctime),
-                         int(st.st_mtime), st.st_uid, st.st_gid,
+            e = NewEntry(basename, name, st.st_dev,
+                         int(st.st_ctime.approx_secs()),
+                         int(st.st_mtime.approx_secs()),
+                         st.st_uid, st.st_gid,
                          st.st_size, st.st_mode, gitmode, sha, flags,
                          0, 0)
         else:
@@ -452,36 +456,9 @@ def reduce_paths(paths):
     paths.sort(reverse=True)
     return paths
 
-
-class MergeIter:
-    def __init__(self, iters):
-        self.iters = iters
-
-    def __len__(self):
-        # FIXME: doesn't remove duplicated entries between iters.
-        # That only happens for parent directories, but will mean the
-        # actual iteration returns fewer entries than this function counts.
-        return sum(len(it) for it in self.iters)
-
-    def __iter__(self):
-        total = len(self)
-        l = [iter(it) for it in self.iters]
-        l = [(next(it),it) for it in l]
-        l = filter(lambda x: x[0], l)
-        count = 0
-        lastname = None
-        while l:
-            if not (count % 1024):
-                progress('bup: merging indexes (%d/%d)\r' % (count, total))
-            l.sort()
-            (e,it) = l.pop()
-            if not e:
-                continue
-            if e.name != lastname:
-                yield e
-                lastname = e.name
-            n = next(it)
-            if n:
-                l.append((n,it))
-            count += 1
-        log('bup: merging indexes (%d/%d), done.\n' % (count, total))
+def merge(*iters):
+    def pfunc(count, total):
+        qprogress('bup: merging indexes (%d/%d)\r' % (count, total))
+    def pfinal(count, total):
+        progress('bup: merging indexes (%d/%d), done.\n' % (count, total))
+    return merge_iter(iters, 1024, pfunc, pfinal, key='name')