mercurial/revlog.py
changeset 5008 3addf4531643
parent 5007 c2febf5420e9
child 5320 8409a2e3a78d
child 5322 fb070713ff36
equal deleted inserted replaced
5007:c2febf5420e9 5008:3addf4531643
    12 
    12 
    13 from node import *
    13 from node import *
    14 from i18n import _
    14 from i18n import _
    15 import binascii, changegroup, errno, ancestor, mdiff, os
    15 import binascii, changegroup, errno, ancestor, mdiff, os
    16 import sha, struct, util, zlib
    16 import sha, struct, util, zlib
       
    17 
       
    18 _pack = struct.pack
       
    19 _unpack = struct.unpack
       
    20 _compress = zlib.compress
       
    21 _decompress = zlib.decompress
       
    22 _sha = sha.new
    17 
    23 
    18 # revlog flags
    24 # revlog flags
    19 REVLOGV0 = 0
    25 REVLOGV0 = 0
    20 REVLOGNG = 1
    26 REVLOGNG = 1
    21 REVLOGNGINLINEDATA = (1 << 16)
    27 REVLOGNGINLINEDATA = (1 << 16)
    44     in a manner that makes it easy to distinguish nodes with the same
    50     in a manner that makes it easy to distinguish nodes with the same
    45     content in the revision graph.
    51     content in the revision graph.
    46     """
    52     """
    47     l = [p1, p2]
    53     l = [p1, p2]
    48     l.sort()
    54     l.sort()
    49     s = sha.new(l[0])
    55     s = _sha(l[0])
    50     s.update(l[1])
    56     s.update(l[1])
    51     s.update(text)
    57     s.update(text)
    52     return s.digest()
    58     return s.digest()
    53 
    59 
    54 def compress(text):
    60 def compress(text):
    57         return ("", text)
    63         return ("", text)
    58     if len(text) < 44:
    64     if len(text) < 44:
    59         if text[0] == '\0':
    65         if text[0] == '\0':
    60             return ("", text)
    66             return ("", text)
    61         return ('u', text)
    67         return ('u', text)
    62     bin = zlib.compress(text)
    68     bin = _compress(text)
    63     if len(bin) > len(text):
    69     if len(bin) > len(text):
    64         if text[0] == '\0':
    70         if text[0] == '\0':
    65             return ("", text)
    71             return ("", text)
    66         return ('u', text)
    72         return ('u', text)
    67     return ("", bin)
    73     return ("", bin)
    72         return bin
    78         return bin
    73     t = bin[0]
    79     t = bin[0]
    74     if t == '\0':
    80     if t == '\0':
    75         return bin
    81         return bin
    76     if t == 'x':
    82     if t == 'x':
    77         return zlib.decompress(bin)
    83         return _decompress(bin)
    78     if t == 'u':
    84     if t == 'u':
    79         return bin[1:]
    85         return bin[1:]
    80     raise RevlogError(_("unknown compression type %r") % t)
    86     raise RevlogError(_("unknown compression type %r") % t)
    81 
    87 
    82 class lazyparser(object):
    88 class lazyparser(object):
   232         if pos < 0:
   238         if pos < 0:
   233             pos += len(self.p.index)
   239             pos += len(self.p.index)
   234         self.p.loadindex(pos)
   240         self.p.loadindex(pos)
   235         return self.p.index[pos]
   241         return self.p.index[pos]
   236     def __getitem__(self, pos):
   242     def __getitem__(self, pos):
   237         return struct.unpack(indexformatng,
   243         return _unpack(indexformatng, self.p.index[pos] or self.load(pos))
   238                              self.p.index[pos] or self.load(pos))
       
   239     def __setitem__(self, pos, item):
   244     def __setitem__(self, pos, item):
   240         self.p.index[pos] = struct.pack(indexformatng, *item)
   245         self.p.index[pos] = _pack(indexformatng, *item)
   241     def __delitem__(self, pos):
   246     def __delitem__(self, pos):
   242         del self.p.index[pos]
   247         del self.p.index[pos]
   243     def insert(self, pos, e):
   248     def insert(self, pos, e):
   244         self.p.index.insert(pos, struct.pack(indexformatng, *e))
   249         self.p.index.insert(pos, _pack(indexformatng, *e))
   245     def append(self, e):
   250     def append(self, e):
   246         self.p.index.append(struct.pack(indexformatng, *e))
   251         self.p.index.append(_pack(indexformatng, *e))
   247 
   252 
   248 class lazymap(object):
   253 class lazymap(object):
   249     """a lazy version of the node map"""
   254     """a lazy version of the node map"""
   250     def __init__(self, parser):
   255     def __init__(self, parser):
   251         self.p = parser
   256         self.p = parser
   264             ret = self.p.index[i]
   269             ret = self.p.index[i]
   265             if not ret:
   270             if not ret:
   266                 self.p.loadindex(i)
   271                 self.p.loadindex(i)
   267                 ret = self.p.index[i]
   272                 ret = self.p.index[i]
   268             if isinstance(ret, str):
   273             if isinstance(ret, str):
   269                 ret = struct.unpack(indexformatng, ret)
   274                 ret = _unpack(indexformatng, ret)
   270             yield ret[7]
   275             yield ret[7]
   271     def __getitem__(self, key):
   276     def __getitem__(self, key):
   272         try:
   277         try:
   273             return self.p.map[key]
   278             return self.p.map[key]
   274         except KeyError:
   279         except KeyError:
   297         data = fp.read()
   302         data = fp.read()
   298         l = len(data)
   303         l = len(data)
   299         while off + s <= l:
   304         while off + s <= l:
   300             cur = data[off:off + s]
   305             cur = data[off:off + s]
   301             off += s
   306             off += s
   302             e = struct.unpack(indexformatv0, cur)
   307             e = _unpack(indexformatv0, cur)
   303             # transform to revlogv1 format
   308             # transform to revlogv1 format
   304             e2 = (offset_type(e[0], 0), e[1], -1, e[2], e[3],
   309             e2 = (offset_type(e[0], 0), e[1], -1, e[2], e[3],
   305                   nodemap[e[4]], nodemap[e[5]], e[6])
   310                   nodemap[e[4]], nodemap[e[5]], e[6])
   306             index.append(e2)
   311             index.append(e2)
   307             nodemap[e[6]] = n
   312             nodemap[e[6]] = n
   310         return index, nodemap, None
   315         return index, nodemap, None
   311 
   316 
   312     def packentry(self, entry, node, version):
   317     def packentry(self, entry, node, version):
   313         e2 = (getoffset(entry[0]), entry[1], entry[3], entry[4],
   318         e2 = (getoffset(entry[0]), entry[1], entry[3], entry[4],
   314               node(entry[5]), node(entry[6]), entry[7])
   319               node(entry[5]), node(entry[6]), entry[7])
   315         return struct.pack(indexformatv0, *e2)
   320         return _pack(indexformatv0, *e2)
   316 
   321 
   317 # index ng:
   322 # index ng:
   318 # 6 bytes offset
   323 # 6 bytes offset
   319 # 2 bytes flags
   324 # 2 bytes flags
   320 # 4 bytes compressed length
   325 # 4 bytes compressed length
   355         nodemap =  {nullid: nullrev}
   360         nodemap =  {nullid: nullrev}
   356         n = off = 0
   361         n = off = 0
   357         # if we're not using lazymap, always read the whole index
   362         # if we're not using lazymap, always read the whole index
   358         data = fp.read()
   363         data = fp.read()
   359         l = len(data) - s
   364         l = len(data) - s
   360         unpack = struct.unpack
       
   361         append = index.append
   365         append = index.append
   362         if inline:
   366         if inline:
   363             cache = (0, data)
   367             cache = (0, data)
   364             while off <= l:
   368             while off <= l:
   365                 e = unpack(indexformatng, data[off:off + s])
   369                 e = _unpack(indexformatng, data[off:off + s])
   366                 nodemap[e[7]] = n
   370                 nodemap[e[7]] = n
   367                 append(e)
   371                 append(e)
   368                 n += 1
   372                 n += 1
   369                 if e[1] < 0:
   373                 if e[1] < 0:
   370                     break
   374                     break
   371                 off += e[1] + s
   375                 off += e[1] + s
   372         else:
   376         else:
   373             while off <= l:
   377             while off <= l:
   374                 e = unpack(indexformatng, data[off:off + s])
   378                 e = _unpack(indexformatng, data[off:off + s])
   375                 nodemap[e[7]] = n
   379                 nodemap[e[7]] = n
   376                 append(e)
   380                 append(e)
   377                 n += 1
   381                 n += 1
   378                 off += s
   382                 off += s
   379 
   383 
   383         index[0] = e
   387         index[0] = e
   384 
   388 
   385         return index, nodemap, cache
   389         return index, nodemap, cache
   386 
   390 
   387     def packentry(self, entry, node, version):
   391     def packentry(self, entry, node, version):
   388         p = struct.pack(indexformatng, *entry)
   392         p = _pack(indexformatng, *entry)
   389         if not entry[3] and not getoffset(entry[0]) and entry[5] == nullrev:
   393         if not entry[3] and not getoffset(entry[0]) and entry[5] == nullrev:
   390             p = struct.pack(versionformat, version) + p[4:]
   394             p = _pack(versionformat, version) + p[4:]
   391         return p
   395         return p
   392 
   396 
   393 class revlog(object):
   397 class revlog(object):
   394     """
   398     """
   395     the underlying revision storage object
   399     the underlying revision storage object