mercurial/changelog.py
changeset 4270 cd7b36b7869c
parent 4267 b11a2fb59cf5
child 4275 73c918c71300
equal deleted inserted replaced
4269:bdbfc2193524 4270:cd7b36b7869c
    24     return text.replace('\0', '\\0')
    24     return text.replace('\0', '\\0')
    25 
    25 
    26 def _string_unescape(text):
    26 def _string_unescape(text):
    27     return text.decode('string_escape')
    27     return text.decode('string_escape')
    28 
    28 
       
    29 class appender:
       
    30     '''the changelog index must be update last on disk, so we use this class
       
    31     to delay writes to it'''
       
    32     def __init__(self, fp, buf):
       
    33         self.data = buf
       
    34         self.fp = fp
       
    35         self.offset = fp.tell()
       
    36         self.size = util.fstat(fp).st_size
       
    37 
       
    38     def end(self):
       
    39         return self.size + len("".join(self.data))
       
    40     def tell(self):
       
    41         return self.offset
       
    42     def flush(self):
       
    43         pass
       
    44     def close(self):
       
    45         close(self.fp)
       
    46 
       
    47     def seek(self, offset, whence=0):
       
    48         '''virtual file offset spans real file and data'''
       
    49         if whence == 0:
       
    50             self.offset = offset
       
    51         elif whence == 1:
       
    52             self.offset += offset
       
    53         elif whence == 2:
       
    54             self.offset = self.end() + offset
       
    55         if self.offset < self.size:
       
    56             self.fp.seek(self.offset)
       
    57 
       
    58     def read(self, count=-1):
       
    59         '''only trick here is reads that span real file and data'''
       
    60         ret = ""
       
    61         old_offset = self.offset
       
    62         if self.offset < self.size:
       
    63             s = self.fp.read(count)
       
    64             ret = s
       
    65             self.offset += len(s)
       
    66             if count > 0:
       
    67                 count -= len(s)
       
    68         if count != 0:
       
    69             doff = self.offset - self.size
       
    70             self.data.insert(0, "".join(self.data))
       
    71             del self.data[1:]
       
    72             s = self.data[0][doff:doff+count]
       
    73             self.offset += len(s)
       
    74             ret += s
       
    75         return ret
       
    76 
       
    77     def write(self, s):
       
    78         self.data.append(s)
       
    79         self.offset += len(s)
       
    80 
    29 class changelog(revlog):
    81 class changelog(revlog):
    30     def __init__(self, opener):
    82     def __init__(self, opener):
    31         revlog.__init__(self, opener, "00changelog.i")
    83         revlog.__init__(self, opener, "00changelog.i")
       
    84 
       
    85     def delayupdate(self):
       
    86         "delay visibility of index updates to other readers"
       
    87         self._realopener = self.opener
       
    88         self.opener = self._appendopener
       
    89         self._delaybuf = []
       
    90 
       
    91     def finalize(self, tr):
       
    92         "finalize index updates"
       
    93         self.opener = self._realopener
       
    94         if self._delaybuf:
       
    95             fp = self.opener(self.indexfile, 'a')
       
    96             fp.write("".join(self._delaybuf))
       
    97             fp.close()
       
    98             del self._delaybuf
       
    99         self.checkinlinesize(tr)
       
   100 
       
   101     def _appendopener(self, name, mode='r'):
       
   102         fp = self._realopener(name, mode)
       
   103         if not name == self.indexfile:
       
   104             return fp
       
   105         return appender(fp, self._delaybuf)
       
   106 
       
   107     def checkinlinesize(self, tr, fp=None):
       
   108         if self.opener == self._appendopener:
       
   109             return
       
   110         return revlog.checkinlinesize(self, tr, fp)
    32 
   111 
    33     def decode_extra(self, text):
   112     def decode_extra(self, text):
    34         extra = {}
   113         extra = {}
    35         for l in text.split('\0'):
   114         for l in text.split('\0'):
    36             if not l:
   115             if not l: