mercurial/repoview.py
changeset 32478 1cc7c96cad75
parent 32477 20c1c2fb8106
child 32479 4c5bc7cbd989
equal deleted inserted replaced
32477:20c1c2fb8106 32478:1cc7c96cad75
     7 # GNU General Public License version 2 or any later version.
     7 # GNU General Public License version 2 or any later version.
     8 
     8 
     9 from __future__ import absolute_import
     9 from __future__ import absolute_import
    10 
    10 
    11 import copy
    11 import copy
    12 import hashlib
       
    13 import struct
       
    14 
    12 
    15 from .node import nullrev
    13 from .node import nullrev
    16 from . import (
    14 from . import (
    17     error,
       
    18     obsolete,
    15     obsolete,
    19     phases,
    16     phases,
    20     tags as tagsmod,
    17     tags as tagsmod,
    21 )
    18 )
    22 
    19 
   124             if p != nullrev and p in domain and p not in ancestors:
   121             if p != nullrev and p in domain and p not in ancestors:
   125                 ancestors.add(p)
   122                 ancestors.add(p)
   126                 stack.append(p)
   123                 stack.append(p)
   127     return ancestors
   124     return ancestors
   128 
   125 
   129 cacheversion = 1
       
   130 cachefile = 'cache/hidden'
       
   131 
       
   132 def cachehash(repo, hideable):
       
   133     """return sha1 hash of repository data to identify a valid cache.
       
   134 
       
   135     We calculate a sha1 of repo heads and the content of the obsstore and write
       
   136     it to the cache. Upon reading we can easily validate by checking the hash
       
   137     against the stored one and discard the cache in case the hashes don't match.
       
   138     """
       
   139     h = hashlib.sha1()
       
   140     h.update(''.join(repo.heads()))
       
   141     h.update('%d' % hash(frozenset(hideable)))
       
   142     return h.digest()
       
   143 
       
   144 def _writehiddencache(cachefile, cachehash, hidden):
       
   145     """write hidden data to a cache file"""
       
   146     data = struct.pack('>%ii' % len(hidden), *sorted(hidden))
       
   147     cachefile.write(struct.pack(">H", cacheversion))
       
   148     cachefile.write(cachehash)
       
   149     cachefile.write(data)
       
   150 
       
   151 def trywritehiddencache(repo, hideable, hidden):
       
   152     """write cache of hidden changesets to disk
       
   153 
       
   154     Will not write the cache if a wlock cannot be obtained lazily.
       
   155     The cache consists of a head of 22byte:
       
   156        2 byte    version number of the cache
       
   157       20 byte    sha1 to validate the cache
       
   158      n*4 byte    hidden revs
       
   159     """
       
   160     wlock = fh = None
       
   161     try:
       
   162         wlock = repo.wlock(wait=False)
       
   163         # write cache to file
       
   164         newhash = cachehash(repo, hideable)
       
   165         fh = repo.vfs.open(cachefile, 'w+b', atomictemp=True)
       
   166         _writehiddencache(fh, newhash, hidden)
       
   167         fh.close()
       
   168     except (IOError, OSError):
       
   169         repo.ui.debug('error writing hidden changesets cache\n')
       
   170     except error.LockHeld:
       
   171         repo.ui.debug('cannot obtain lock to write hidden changesets cache\n')
       
   172     finally:
       
   173         if wlock:
       
   174             wlock.release()
       
   175 
       
   176 def _readhiddencache(repo, cachefilename, newhash):
       
   177     hidden = fh = None
       
   178     try:
       
   179         if repo.vfs.exists(cachefile):
       
   180             fh = repo.vfs.open(cachefile, 'rb')
       
   181             version, = struct.unpack(">H", fh.read(2))
       
   182             oldhash = fh.read(20)
       
   183             if (cacheversion, oldhash) == (version, newhash):
       
   184                 # cache is valid, so we can start reading the hidden revs
       
   185                 data = fh.read()
       
   186                 count = len(data) / 4
       
   187                 hidden = frozenset(struct.unpack('>%ii' % count, data))
       
   188         return hidden
       
   189     except struct.error:
       
   190         repo.ui.debug('corrupted hidden cache\n')
       
   191         # No need to fix the content as it will get rewritten
       
   192         return None
       
   193     except (IOError, OSError):
       
   194         repo.ui.debug('cannot read hidden cache\n')
       
   195         return None
       
   196     finally:
       
   197         if fh:
       
   198             fh.close()
       
   199 
       
   200 def tryreadcache(repo, hideable):
       
   201     """read a cache if the cache exists and is valid, otherwise returns None."""
       
   202     newhash = cachehash(repo, hideable)
       
   203     return _readhiddencache(repo, cachefile, newhash)
       
   204 
       
   205 def computehidden(repo):
   126 def computehidden(repo):
   206     """compute the set of hidden revision to filter
   127     """compute the set of hidden revision to filter
   207 
   128 
   208     During most operation hidden should be filtered."""
   129     During most operation hidden should be filtered."""
   209     assert not repo.changelog.filteredrevs
   130     assert not repo.changelog.filteredrevs
   210 
   131 
   211     hidden = frozenset()
   132     hidden = frozenset()
   212     hideable = hideablerevs(repo)
   133     hideable = hideablerevs(repo)
   213     if hideable:
   134     if hideable:
   214         cl = repo.changelog
   135         cl = repo.changelog
   215         hidden = tryreadcache(repo, hideable)
   136         hidden = frozenset(_getstatichidden(repo))
   216         if hidden is None:
       
   217             hidden = frozenset(_getstatichidden(repo))
       
   218             trywritehiddencache(repo, hideable, hidden)
       
   219 
   137 
   220         # check if we have wd parents, bookmarks or tags pointing to hidden
   138         # check if we have wd parents, bookmarks or tags pointing to hidden
   221         # changesets and remove those.
   139         # changesets and remove those.
   222         dynamic = hidden & revealedrevs(repo)
   140         dynamic = hidden & revealedrevs(repo)
   223         if dynamic:
   141         if dynamic: