mercurial/bundlerepo.py
changeset 1981 736b6c96bbbc
parent 1980 dfb796786337
child 2074 01ee43dda681
equal deleted inserted replaced
1980:dfb796786337 1981:736b6c96bbbc
    11 """
    11 """
    12 
    12 
    13 from node import *
    13 from node import *
    14 from i18n import gettext as _
    14 from i18n import gettext as _
    15 from demandload import demandload
    15 from demandload import demandload
    16 demandload(globals(), "util os struct")
    16 demandload(globals(), "changegroup util os struct")
    17 
    17 
    18 import localrepo, changelog, manifest, filelog, revlog
    18 import localrepo, changelog, manifest, filelog, revlog
    19 
       
    20 def getchunk(source):
       
    21     """get a chunk from a group"""
       
    22     d = source.read(4)
       
    23     if not d:
       
    24         return ""
       
    25     l = struct.unpack(">l", d)[0]
       
    26     if l <= 4:
       
    27         return ""
       
    28     d = source.read(l - 4)
       
    29     if len(d) < l - 4:
       
    30         raise util.Abort(_("premature EOF reading chunk"
       
    31                            " (got %d bytes, expected %d)")
       
    32                           % (len(d), l - 4))
       
    33     return d
       
    34 
    19 
    35 class bundlerevlog(revlog.revlog):
    20 class bundlerevlog(revlog.revlog):
    36     def __init__(self, opener, indexfile, datafile, bundlefile,
    21     def __init__(self, opener, indexfile, datafile, bundlefile,
    37                  linkmapper=None):
    22                  linkmapper=None):
    38         # How it works:
    23         # How it works:
    44         # len(index[r]). If the tuple is bigger than 7, it is a bundle
    29         # len(index[r]). If the tuple is bigger than 7, it is a bundle
    45         # (it is bigger since we store the node to which the delta is)
    30         # (it is bigger since we store the node to which the delta is)
    46         #
    31         #
    47         revlog.revlog.__init__(self, opener, indexfile, datafile)
    32         revlog.revlog.__init__(self, opener, indexfile, datafile)
    48         self.bundlefile = bundlefile
    33         self.bundlefile = bundlefile
    49         def genchunk():
    34         def chunkpositer():
    50             while 1:
    35             for chunk in changegroup.chunkiter(bundlefile):
    51                 pos = bundlefile.tell()
    36                 pos = bundlefile.tell()
    52                 chunk = getchunk(bundlefile)
    37                 yield chunk, pos - len(chunk)
    53                 if not chunk:
       
    54                     break
       
    55                 yield chunk, pos + 4 # XXX struct.calcsize(">l") == 4
       
    56         n = self.count()
    38         n = self.count()
    57         prev = None
    39         prev = None
    58         for chunk, start in genchunk():
    40         for chunk, start in chunkpositer():
    59             size = len(chunk)
    41             size = len(chunk)
    60             if size < 80:
    42             if size < 80:
    61                 raise util.Abort("invalid changegroup")
    43                 raise util.Abort("invalid changegroup")
    62             start += 80
    44             start += 80
    63             size -= 80
    45             size -= 80
   192         self.manifest = bundlemanifest(self.opener, self.bundlefile,
   174         self.manifest = bundlemanifest(self.opener, self.bundlefile,
   193                                        self.changelog.rev)
   175                                        self.changelog.rev)
   194         # dict with the mapping 'filename' -> position in the bundle
   176         # dict with the mapping 'filename' -> position in the bundle
   195         self.bundlefilespos = {}
   177         self.bundlefilespos = {}
   196         while 1:
   178         while 1:
   197                 f = getchunk(self.bundlefile)
   179             f = changegroup.getchunk(self.bundlefile)
   198                 if not f:
   180             if not f:
   199                     break
   181                 break
   200                 self.bundlefilespos[f] = self.bundlefile.tell()
   182             self.bundlefilespos[f] = self.bundlefile.tell()
   201                 while getchunk(self.bundlefile):
   183             for c in changegroup.chunkiter(self.bundlefile):
   202                     pass
   184                 pass
   203 
   185 
   204     def dev(self):
   186     def dev(self):
   205         return -1
   187         return -1
   206 
   188 
   207     def file(self, f):
   189     def file(self, f):