comparison mercurial/scmutil.py @ 20045:b3684fd2ff1a

scmutil.filecache: support watching over multiple files
author Siddharth Agarwal <sid0@fb.com>
date Sat, 16 Nov 2013 13:29:39 -0800
parents d38de18d187a
children 589d6bb5b18d
comparison
equal deleted inserted replaced
20044:d38de18d187a 20045:b3684fd2ff1a
784 def refresh(self): 784 def refresh(self):
785 for entry in self._entries: 785 for entry in self._entries:
786 entry.refresh() 786 entry.refresh()
787 787
788 class filecache(object): 788 class filecache(object):
789 '''A property like decorator that tracks a file under .hg/ for updates. 789 '''A property like decorator that tracks files under .hg/ for updates.
790 790
791 Records stat info when called in _filecache. 791 Records stat info when called in _filecache.
792 792
793 On subsequent calls, compares old stat info with new info, and recreates 793 On subsequent calls, compares old stat info with new info, and recreates the
794 the object when needed, updating the new stat info in _filecache. 794 object when any of the files changes, updating the new stat info in
795 _filecache.
795 796
796 Mercurial either atomic renames or appends for files under .hg, 797 Mercurial either atomic renames or appends for files under .hg,
797 so to ensure the cache is reliable we need the filesystem to be able 798 so to ensure the cache is reliable we need the filesystem to be able
798 to tell us if a file has been replaced. If it can't, we fallback to 799 to tell us if a file has been replaced. If it can't, we fallback to
799 recreating the object on every call (essentially the same behaviour as 800 recreating the object on every call (essentially the same behaviour as
800 propertycache).''' 801 propertycache).
801 def __init__(self, path): 802
802 self.path = path 803 '''
804 def __init__(self, *paths):
805 self.paths = paths
803 806
804 def join(self, obj, fname): 807 def join(self, obj, fname):
805 """Used to compute the runtime path of the cached file. 808 """Used to compute the runtime path of a cached file.
806 809
807 Users should subclass filecache and provide their own version of this 810 Users should subclass filecache and provide their own version of this
808 function to call the appropriate join function on 'obj' (an instance 811 function to call the appropriate join function on 'obj' (an instance
809 of the class that its member function was decorated). 812 of the class that its member function was decorated).
810 """ 813 """
825 828
826 if entry: 829 if entry:
827 if entry.changed(): 830 if entry.changed():
828 entry.obj = self.func(obj) 831 entry.obj = self.func(obj)
829 else: 832 else:
830 path = self.join(obj, self.path) 833 paths = [self.join(obj, path) for path in self.paths]
831 834
832 # We stat -before- creating the object so our cache doesn't lie if 835 # We stat -before- creating the object so our cache doesn't lie if
833 # a writer modified between the time we read and stat 836 # a writer modified between the time we read and stat
834 entry = filecachesubentry(path, True) 837 entry = filecacheentry(paths, True)
835 entry.obj = self.func(obj) 838 entry.obj = self.func(obj)
836 839
837 obj._filecache[self.name] = entry 840 obj._filecache[self.name] = entry
838 841
839 obj.__dict__[self.name] = entry.obj 842 obj.__dict__[self.name] = entry.obj
841 844
842 def __set__(self, obj, value): 845 def __set__(self, obj, value):
843 if self.name not in obj._filecache: 846 if self.name not in obj._filecache:
844 # we add an entry for the missing value because X in __dict__ 847 # we add an entry for the missing value because X in __dict__
845 # implies X in _filecache 848 # implies X in _filecache
846 ce = filecachesubentry(self.join(obj, self.path), False) 849 paths = [self.join(obj, path) for path in self.paths]
850 ce = filecacheentry(paths, False)
847 obj._filecache[self.name] = ce 851 obj._filecache[self.name] = ce
848 else: 852 else:
849 ce = obj._filecache[self.name] 853 ce = obj._filecache[self.name]
850 854
851 ce.obj = value # update cached copy 855 ce.obj = value # update cached copy