mercurial/revlog.py
changeset 76 d993ebd69d28
parent 73 ee1cbe841e01
child 77 bed15e766511
equal deleted inserted replaced
75:b942bbe4bb84 76:d993ebd69d28
    26     return sha.sha(l[0] + l[1] + text).digest()
    26     return sha.sha(l[0] + l[1] + text).digest()
    27 
    27 
    28 nullid = "\0" * 20
    28 nullid = "\0" * 20
    29 indexformat = ">4l20s20s20s"
    29 indexformat = ">4l20s20s20s"
    30 
    30 
       
    31 class lazyparser:
       
    32     def __init__(self, data):
       
    33         self.data = data
       
    34         self.s = struct.calcsize(indexformat)
       
    35         self.l = len(data)/self.s
       
    36         self.index = [None] * self.l
       
    37         self.map = {nullid: -1}
       
    38 
       
    39         if 0:
       
    40             n = 0
       
    41             i = self.data
       
    42             s = struct.calcsize(indexformat)
       
    43             for f in xrange(0, len(i), s):
       
    44                 # offset, size, base, linkrev, p1, p2, nodeid
       
    45                 e = struct.unpack(indexformat, i[f:f + s])
       
    46                 self.map[e[6]] = n
       
    47                 self.index.append(e)
       
    48                 n += 1
       
    49 
       
    50     def load(self, pos):
       
    51         block = pos / 1000
       
    52         i = block * 1000
       
    53         end = min(self.l, i + 1000)
       
    54         while i < end:
       
    55             d = self.data[i * self.s: (i + 1) * self.s]
       
    56             e = struct.unpack(indexformat, d)
       
    57             self.index[i] = e
       
    58             self.map[e[6]] = i
       
    59             i += 1
       
    60         
       
    61 class lazyindex:
       
    62     def __init__(self, parser):
       
    63         self.p = parser
       
    64     def __len__(self):
       
    65         return len(self.p.index)
       
    66     def __getitem__(self, pos):
       
    67         i = self.p.index[pos]
       
    68         if not i:
       
    69             self.p.load(pos)
       
    70             return self.p.index[pos]
       
    71         return i
       
    72     def append(self, e):
       
    73         self.p.index.append(e)
       
    74         
       
    75 class lazymap:
       
    76     def __init__(self, parser):
       
    77         self.p = parser
       
    78     def load(self, key):
       
    79         n = self.p.data.find(key)
       
    80         if n < 0: raise KeyError(key)
       
    81         pos = n / self.p.s
       
    82         self.p.load(pos)
       
    83     def __contains__(self, key):
       
    84         try:
       
    85             self.p.map[key]
       
    86             return True
       
    87         except KeyError:
       
    88             return False
       
    89     def __getitem__(self, key):
       
    90         try:
       
    91             return self.p.map[key]
       
    92         except KeyError:
       
    93             self.load(key)
       
    94             return self.p.map[key]
       
    95     def __setitem__(self, key, val):
       
    96         self.p.map[key] = val
       
    97 
    31 class revlog:
    98 class revlog:
    32     def __init__(self, opener, indexfile, datafile):
    99     def __init__(self, opener, indexfile, datafile):
    33         self.indexfile = indexfile
   100         self.indexfile = indexfile
    34         self.datafile = datafile
   101         self.datafile = datafile
    35         self.index = []
       
    36         self.opener = opener
   102         self.opener = opener
    37         self.cache = None
   103         self.cache = None
    38         # read the whole index for now, handle on-demand later
   104         # read the whole index for now, handle on-demand later
    39         try:
   105         try:
    40             n = 0
       
    41             i = self.opener(self.indexfile).read()
   106             i = self.opener(self.indexfile).read()
    42             s = struct.calcsize(indexformat)
       
    43 
       
    44             # preallocate arrays
       
    45             l = len(i)/s
       
    46             self.index = [None] * l
       
    47             m = [None] * l
       
    48             
       
    49             for f in xrange(0, len(i), s):
       
    50                 # offset, size, base, linkrev, p1, p2, nodeid
       
    51                 e = struct.unpack(indexformat, i[f:f + s])
       
    52                 self.index[n] = e
       
    53                 m[n] = (e[6], n)
       
    54                 n += 1
       
    55 
       
    56             self.nodemap = dict(m)
       
    57         except IOError:
   107         except IOError:
    58             self.nodemap = {}
   108             i = ""
    59         self.nodemap[nullid] = -1
   109         parser = lazyparser(i)
       
   110         self.index = lazyindex(parser)
       
   111         self.nodemap = lazymap(parser)
    60 
   112 
    61     def tip(self): return self.node(len(self.index) - 1)
   113     def tip(self): return self.node(len(self.index) - 1)
    62     def count(self): return len(self.index)
   114     def count(self): return len(self.index)
    63     def node(self, rev): return (rev < 0) and nullid or self.index[rev][6]
   115     def node(self, rev): return (rev < 0) and nullid or self.index[rev][6]
    64     def rev(self, node): return self.nodemap[node]
   116     def rev(self, node): return self.nodemap[node]