508 assert size is not None |
508 assert size is not None |
509 assert mtime is not None |
509 assert mtime is not None |
510 size = size & rangemask |
510 size = size & rangemask |
511 mtime = mtime & rangemask |
511 mtime = mtime & rangemask |
512 item = DirstateItem.new_normal(mode, size, mtime) |
512 item = DirstateItem.new_normal(mode, size, mtime) |
513 self._rustmap.addfile(f, item) |
513 self._map.addfile(f, item) |
514 if added: |
514 if added: |
515 self.copymap.pop(f, None) |
515 self.copymap.pop(f, None) |
516 |
516 |
517 def reset_state( |
517 def reset_state( |
518 self, |
518 self, |
543 # copy information are now outdated |
543 # copy information are now outdated |
544 # (maybe new information should be in directly passed to this function) |
544 # (maybe new information should be in directly passed to this function) |
545 self.copymap.pop(filename, None) |
545 self.copymap.pop(filename, None) |
546 |
546 |
547 if not (p1_tracked or p2_tracked or wc_tracked): |
547 if not (p1_tracked or p2_tracked or wc_tracked): |
548 self._rustmap.drop_item_and_copy_source(filename) |
548 self._map.drop_item_and_copy_source(filename) |
549 elif merged: |
549 elif merged: |
550 # XXX might be merged and removed ? |
550 # XXX might be merged and removed ? |
551 entry = self.get(filename) |
551 entry = self.get(filename) |
552 if entry is not None and entry.tracked: |
552 if entry is not None and entry.tracked: |
553 # XXX mostly replicate dirstate.other parent. We should get |
553 # XXX mostly replicate dirstate.other parent. We should get |
619 entry = self.get(f) |
619 entry = self.get(f) |
620 if entry is None: |
620 if entry is None: |
621 return False |
621 return False |
622 else: |
622 else: |
623 if entry.added: |
623 if entry.added: |
624 self._rustmap.drop_item_and_copy_source(f) |
624 self._map.drop_item_and_copy_source(f) |
625 else: |
625 else: |
626 self._rustmap.removefile(f, in_merge=True) |
626 self._map.removefile(f, in_merge=True) |
627 return True |
627 return True |
628 |
628 |
629 def removefile(self, *args, **kwargs): |
629 def removefile(self, *args, **kwargs): |
630 return self._rustmap.removefile(*args, **kwargs) |
630 return self._map.removefile(*args, **kwargs) |
631 |
631 |
632 def get(self, *args, **kwargs): |
632 def get(self, *args, **kwargs): |
633 return self._rustmap.get(*args, **kwargs) |
633 return self._map.get(*args, **kwargs) |
634 |
634 |
635 @property |
635 @property |
636 def copymap(self): |
636 def copymap(self): |
637 return self._rustmap.copymap() |
637 return self._map.copymap() |
638 |
638 |
639 def debug_iter(self, all): |
639 def debug_iter(self, all): |
640 """ |
640 """ |
641 Return an iterator of (filename, state, mode, size, mtime) tuples |
641 Return an iterator of (filename, state, mode, size, mtime) tuples |
642 |
642 |
643 `all`: also include with `state == b' '` dirstate tree nodes that |
643 `all`: also include with `state == b' '` dirstate tree nodes that |
644 don't have an associated `DirstateItem`. |
644 don't have an associated `DirstateItem`. |
645 |
645 |
646 """ |
646 """ |
647 return self._rustmap.debug_iter(all) |
647 return self._map.debug_iter(all) |
648 |
648 |
649 def preload(self): |
649 def preload(self): |
650 self._rustmap |
650 self._map |
651 |
651 |
652 def clear(self): |
652 def clear(self): |
653 self._rustmap.clear() |
653 self._map.clear() |
654 self.setparents( |
654 self.setparents( |
655 self._nodeconstants.nullid, self._nodeconstants.nullid |
655 self._nodeconstants.nullid, self._nodeconstants.nullid |
656 ) |
656 ) |
657 util.clearcachedproperty(self, b"_dirs") |
657 util.clearcachedproperty(self, b"_dirs") |
658 util.clearcachedproperty(self, b"_alldirs") |
658 util.clearcachedproperty(self, b"_alldirs") |
659 util.clearcachedproperty(self, b"dirfoldmap") |
659 util.clearcachedproperty(self, b"dirfoldmap") |
660 |
660 |
661 def items(self): |
661 def items(self): |
662 return self._rustmap.items() |
662 return self._map.items() |
663 |
663 |
664 def keys(self): |
664 def keys(self): |
665 return iter(self._rustmap) |
665 return iter(self._map) |
666 |
666 |
667 def __contains__(self, key): |
667 def __contains__(self, key): |
668 return key in self._rustmap |
668 return key in self._map |
669 |
669 |
670 def __getitem__(self, item): |
670 def __getitem__(self, item): |
671 return self._rustmap[item] |
671 return self._map[item] |
672 |
672 |
673 def __len__(self): |
673 def __len__(self): |
674 return len(self._rustmap) |
674 return len(self._map) |
675 |
675 |
676 def __iter__(self): |
676 def __iter__(self): |
677 return iter(self._rustmap) |
677 return iter(self._map) |
678 |
678 |
679 # forward for python2,3 compat |
679 # forward for python2,3 compat |
680 iteritems = items |
680 iteritems = items |
681 |
681 |
682 def _opendirstatefile(self): |
682 def _opendirstatefile(self): |
711 # TODO: move this the whole loop to Rust where `iter_mut` |
711 # TODO: move this the whole loop to Rust where `iter_mut` |
712 # enables in-place mutation of elements of a collection while |
712 # enables in-place mutation of elements of a collection while |
713 # iterating it, without mutating the collection itself. |
713 # iterating it, without mutating the collection itself. |
714 candidatefiles = [ |
714 candidatefiles = [ |
715 (f, s) |
715 (f, s) |
716 for f, s in self._rustmap.items() |
716 for f, s in self._map.items() |
717 if s.merged or s.from_p2 |
717 if s.merged or s.from_p2 |
718 ] |
718 ] |
719 for f, s in candidatefiles: |
719 for f, s in candidatefiles: |
720 # Discard "merged" markers when moving away from a merge state |
720 # Discard "merged" markers when moving away from a merge state |
721 if s.merged: |
721 if s.merged: |
791 if self.docket.uuid: |
791 if self.docket.uuid: |
792 # TODO: use mmap when possible |
792 # TODO: use mmap when possible |
793 data = self._opener.read(self.docket.data_filename()) |
793 data = self._opener.read(self.docket.data_filename()) |
794 else: |
794 else: |
795 data = b'' |
795 data = b'' |
796 self._rustmap = rustmod.DirstateMap.new_v2( |
796 self._map = rustmod.DirstateMap.new_v2( |
797 data, self.docket.data_size, self.docket.tree_metadata |
797 data, self.docket.data_size, self.docket.tree_metadata |
798 ) |
798 ) |
799 parents = self.docket.parents |
799 parents = self.docket.parents |
800 else: |
800 else: |
801 self._rustmap, parents = rustmod.DirstateMap.new_v1( |
801 self._map, parents = rustmod.DirstateMap.new_v1( |
802 self._readdirstatefile() |
802 self._readdirstatefile() |
803 ) |
803 ) |
804 |
804 |
805 if parents and not self._dirtyparents: |
805 if parents and not self._dirtyparents: |
806 self.setparents(*parents) |
806 self.setparents(*parents) |
807 |
807 |
808 self.__contains__ = self._rustmap.__contains__ |
808 self.__contains__ = self._map.__contains__ |
809 self.__getitem__ = self._rustmap.__getitem__ |
809 self.__getitem__ = self._map.__getitem__ |
810 self.get = self._rustmap.get |
810 self.get = self._map.get |
811 return self._rustmap |
811 return self._map |
812 |
812 |
813 def write(self, tr, st, now): |
813 def write(self, tr, st, now): |
814 if not self._use_dirstate_v2: |
814 if not self._use_dirstate_v2: |
815 p1, p2 = self.parents() |
815 p1, p2 = self.parents() |
816 packed = self._rustmap.write_v1(p1, p2, now) |
816 packed = self._map.write_v1(p1, p2, now) |
817 st.write(packed) |
817 st.write(packed) |
818 st.close() |
818 st.close() |
819 self._dirtyparents = False |
819 self._dirtyparents = False |
820 return |
820 return |
821 |
821 |
822 # We can only append to an existing data file if there is one |
822 # We can only append to an existing data file if there is one |
823 can_append = self.docket.uuid is not None |
823 can_append = self.docket.uuid is not None |
824 packed, meta, append = self._rustmap.write_v2(now, can_append) |
824 packed, meta, append = self._map.write_v2(now, can_append) |
825 if append: |
825 if append: |
826 docket = self.docket |
826 docket = self.docket |
827 data_filename = docket.data_filename() |
827 data_filename = docket.data_filename() |
828 if tr: |
828 if tr: |
829 tr.add(data_filename, docket.data_size) |
829 tr.add(data_filename, docket.data_size) |
862 tr.addpostclose(category, unlink) |
862 tr.addpostclose(category, unlink) |
863 else: |
863 else: |
864 unlink() |
864 unlink() |
865 self._docket = new_docket |
865 self._docket = new_docket |
866 # Reload from the newly-written file |
866 # Reload from the newly-written file |
867 util.clearcachedproperty(self, b"_rustmap") |
867 util.clearcachedproperty(self, b"_map") |
868 self._dirtyparents = False |
868 self._dirtyparents = False |
869 |
869 |
870 @propertycache |
870 @propertycache |
871 def filefoldmap(self): |
871 def filefoldmap(self): |
872 """Returns a dictionary mapping normalized case paths to their |
872 """Returns a dictionary mapping normalized case paths to their |
873 non-normalized versions. |
873 non-normalized versions. |
874 """ |
874 """ |
875 return self._rustmap.filefoldmapasdict() |
875 return self._map.filefoldmapasdict() |
876 |
876 |
877 def hastrackeddir(self, d): |
877 def hastrackeddir(self, d): |
878 return self._rustmap.hastrackeddir(d) |
878 return self._map.hastrackeddir(d) |
879 |
879 |
880 def hasdir(self, d): |
880 def hasdir(self, d): |
881 return self._rustmap.hasdir(d) |
881 return self._map.hasdir(d) |
882 |
882 |
883 @propertycache |
883 @propertycache |
884 def identity(self): |
884 def identity(self): |
885 self._rustmap |
885 self._map |
886 return self.identity |
886 return self.identity |
887 |
887 |
888 @propertycache |
888 @propertycache |
889 def dirfoldmap(self): |
889 def dirfoldmap(self): |
890 f = {} |
890 f = {} |
891 normcase = util.normcase |
891 normcase = util.normcase |
892 for name in self._rustmap.tracked_dirs(): |
892 for name in self._map.tracked_dirs(): |
893 f[normcase(name)] = name |
893 f[normcase(name)] = name |
894 return f |
894 return f |
895 |
895 |
896 def set_possibly_dirty(self, filename): |
896 def set_possibly_dirty(self, filename): |
897 """record that the current state of the file on disk is unknown""" |
897 """record that the current state of the file on disk is unknown""" |
898 entry = self[filename] |
898 entry = self[filename] |
899 entry.set_possibly_dirty() |
899 entry.set_possibly_dirty() |
900 self._rustmap.set_dirstate_item(filename, entry) |
900 self._map.set_dirstate_item(filename, entry) |
901 |
901 |
902 def set_clean(self, filename, mode, size, mtime): |
902 def set_clean(self, filename, mode, size, mtime): |
903 """mark a file as back to a clean state""" |
903 """mark a file as back to a clean state""" |
904 entry = self[filename] |
904 entry = self[filename] |
905 mtime = mtime & rangemask |
905 mtime = mtime & rangemask |
906 size = size & rangemask |
906 size = size & rangemask |
907 entry.set_clean(mode, size, mtime) |
907 entry.set_clean(mode, size, mtime) |
908 self._rustmap.set_dirstate_item(filename, entry) |
908 self._map.set_dirstate_item(filename, entry) |
909 self._rustmap.copymap().pop(filename, None) |
909 self._map.copymap().pop(filename, None) |
910 |
910 |
911 def __setitem__(self, key, value): |
911 def __setitem__(self, key, value): |
912 assert isinstance(value, DirstateItem) |
912 assert isinstance(value, DirstateItem) |
913 self._rustmap.set_dirstate_item(key, value) |
913 self._map.set_dirstate_item(key, value) |