]> arthur.barton.de Git - bup.git/commitdiff
vfs: File.open() needs to do a seek(0) on the cached FileReader.
authorAvery Pennarun <apenwarr@gmail.com>
Fri, 9 Jul 2010 04:38:32 +0000 (00:38 -0400)
committerAvery Pennarun <apenwarr@gmail.com>
Fri, 9 Jul 2010 04:40:43 +0000 (00:40 -0400)
Otherwise if you open a file, read through it, and close it, then do it
again, you'll get zero bytes the second time.

To make this efficient, change seek() to not discard its _chunkiter every
single time; instead, keep the _chunkiter around until trying to read() from
a location that *isn't* the current offset.  Now seeking around in the file
is cheap.

Signed-off-by: Avery Pennarun <apenwarr@gmail.com>
lib/bup/vfs.py
t/test.sh

index ea33818647398c9c247800f71e0ca166ea291376..60287935e0014105ea89937c4d58a662fd3e4ecc 100644 (file)
@@ -89,6 +89,7 @@ class _ChunkReader:
         else:
             self.it = None
             self.blob = ''.join(cp().join(hash.encode('hex')))[startofs:]
+        self.ofs = startofs
 
     def next(self, size):
         out = ''
@@ -105,6 +106,7 @@ class _ChunkReader:
             if not self.it:
                 break
         log('next(%d) returned %d\n' % (size, len(out)))
+        self.ofs += len(out)
         return out
 
 
@@ -117,9 +119,6 @@ class _FileReader:
         self.reader = None
 
     def seek(self, ofs):
-        if self.ofs == ofs:
-            return
-        self.reader = None
         if ofs > self.size:
             self.ofs = self.size
         elif ofs < 0:
@@ -133,7 +132,7 @@ class _FileReader:
     def read(self, count = -1):
         if count < 0:
             count = self.size - self.ofs
-        if not self.reader:
+        if not self.reader or self.reader.ofs != self.ofs:
             self.reader = _ChunkReader(self.hash, self.isdir, self.ofs)
         try:
             buf = self.reader.next(count)
@@ -244,15 +243,17 @@ class File(Node):
         if not self._filereader:
             self._filereader = _FileReader(self.hash, self.size(),
                                            self.bupmode == git.BUP_CHUNKED)
+        self._filereader.seek(0)
         return self._filereader
     
     def size(self):
         if self._cached_size == None:
-            log('<<<<File.size() is calculating\n')
+            log('<<<<File.size() is calculating...\n')
             if self.bupmode == git.BUP_CHUNKED:
                 self._cached_size = _total_size(self.hash)
             else:
                 self._cached_size = _chunk_len(self.hash)
+            log('<<<<File.size() done.\n')
         return self._cached_size
 
 
index 41e09acfb9c4e7bffca24f0994ba0b61f32a1732..1dca9f10a36ef7008c4a021b360a6cb0125a49ee 100755 (executable)
--- a/t/test.sh
+++ b/t/test.sh
@@ -166,9 +166,11 @@ WVSTART "save/git-fsck"
 WVSTART "ftp"
 WVPASS bup ftp "cat /master/latest/$TOP/$D/b" >$D/b.new
 WVPASS bup ftp "cat /master/latest/$TOP/$D/f" >$D/f.new
+WVPASS bup ftp "cat /master/latest/$TOP/$D/f"{,} >$D/f2.new
 WVPASS bup ftp "cat /master/latest/$TOP/$D/a" >$D/a.new
 WVPASSEQ "$(sha1sum <$D/b)" "$(sha1sum <$D/b.new)"
 WVPASSEQ "$(sha1sum <$D/f)" "$(sha1sum <$D/f.new)"
+WVPASSEQ "$(cat $D/f.new{,} | sha1sum)" "$(sha1sum <$D/f2.new)"
 WVPASSEQ "$(sha1sum <$D/a)" "$(sha1sum <$D/a.new)"
 
 WVSTART "fsck"