8 from revlog import * |
8 from revlog import * |
9 from i18n import gettext as _ |
9 from i18n import gettext as _ |
10 from demandload import * |
10 from demandload import * |
11 demandload(globals(), "array bisect struct") |
11 demandload(globals(), "array bisect struct") |
12 |
12 |
13 class manifestflags(dict): |
13 class manifestdict(dict): |
14 def __init__(self, mapping={}): |
14 def __init__(self, mapping={}): |
15 dict.__init__(self, mapping) |
15 dict.__init__(self, mapping) |
16 def __getitem__(self, f): |
16 def __getitem__(self, f): |
17 raise "oops" |
17 return self.node(f) |
|
18 def get(self, f, default=None): |
|
19 try: |
|
20 return dict.__getitem__(self, f)[:20] |
|
21 except KeyError: |
|
22 return default |
|
23 def __setitem__(self, f, node): |
|
24 fl = self.flags(f) |
|
25 dict.__setitem__(self, f, node + fl) |
|
26 def node(self, f): |
|
27 return dict.__getitem__(self, f)[:20] |
18 def flags(self, f): |
28 def flags(self, f): |
19 return dict.__getitem__(self, f) |
29 return dict.get(self, f, "")[20:] |
20 def execf(self, f): |
30 def execf(self, f): |
21 "test for executable in manifest flags" |
31 "test for executable in manifest flags" |
22 return "x" in self.get(f, "") |
32 return "x" in self.flags(f) |
23 def linkf(self, f): |
33 def linkf(self, f): |
24 "test for symlink in manifest flags" |
34 "test for symlink in manifest flags" |
25 return "l" in self.get(f, "") |
35 return "l" in self.flags(f) |
|
36 def rawset(self, f, node, flags): |
|
37 dict.__setitem__(self, f, node + flags) |
26 def set(self, f, execf=False, linkf=False): |
38 def set(self, f, execf=False, linkf=False): |
|
39 n = dict.get(self, f, nullid)[:20] |
27 fl = "" |
40 fl = "" |
28 if execf: fl = "x" |
41 if execf: fl = "x" |
29 if linkf: fl = "l" |
42 if linkf: fl = "l" |
30 self[f] = fl |
43 dict.__setitem__(self, f, n + fl) |
31 def copy(self): |
44 def copy(self): |
32 return manifestflags(dict.copy(self)) |
45 return manifestdict(dict.copy(self)) |
33 |
46 |
34 class manifest(revlog): |
47 class manifest(revlog): |
35 def __init__(self, opener, defversion=REVLOGV0): |
48 def __init__(self, opener, defversion=REVLOGV0): |
36 self.mapcache = None |
49 self.mapcache = None |
37 self.listcache = None |
50 self.listcache = None |
38 revlog.__init__(self, opener, "00manifest.i", "00manifest.d", |
51 revlog.__init__(self, opener, "00manifest.i", "00manifest.d", |
39 defversion) |
52 defversion) |
40 |
53 |
41 def read(self, node): |
54 def read(self, node): |
42 if node == nullid: return {} # don't upset local cache |
55 if node == nullid: return manifestdict() # don't upset local cache |
43 if self.mapcache and self.mapcache[0] == node: |
56 if self.mapcache and self.mapcache[0] == node: |
44 return self.mapcache[1] |
57 return self.mapcache[1] |
45 text = self.revision(node) |
58 text = self.revision(node) |
46 map = {} |
|
47 flag = manifestflags() |
|
48 self.listcache = array.array('c', text) |
59 self.listcache = array.array('c', text) |
49 lines = text.splitlines(1) |
60 lines = text.splitlines(1) |
|
61 mapping = manifestdict() |
50 for l in lines: |
62 for l in lines: |
51 (f, n) = l.split('\0') |
63 (f, n) = l.split('\0') |
52 map[f] = bin(n[:40]) |
64 mapping.rawset(f, bin(n[:40]), n[40:-1]) |
53 flag[f] = n[40:-1] |
65 self.mapcache = (node, mapping) |
54 self.mapcache = (node, map, flag) |
66 return mapping |
55 return map |
|
56 |
67 |
57 def readflags(self, node): |
68 def readflags(self, node): |
58 if node == nullid: return manifestflags() # don't upset local cache |
69 return self.read(node) |
59 if not self.mapcache or self.mapcache[0] != node: |
|
60 self.read(node) |
|
61 return self.mapcache[2] |
|
62 |
70 |
63 def diff(self, a, b): |
71 def diff(self, a, b): |
64 return mdiff.textdiff(str(a), str(b)) |
72 return mdiff.textdiff(str(a), str(b)) |
65 |
73 |
66 def _search(self, m, s, lo=0, hi=None): |
74 def _search(self, m, s, lo=0, hi=None): |
105 |
113 |
106 def find(self, node, f): |
114 def find(self, node, f): |
107 '''look up entry for a single file efficiently. |
115 '''look up entry for a single file efficiently. |
108 return (node, flag) pair if found, (None, None) if not.''' |
116 return (node, flag) pair if found, (None, None) if not.''' |
109 if self.mapcache and node == self.mapcache[0]: |
117 if self.mapcache and node == self.mapcache[0]: |
110 return self.mapcache[1].get(f), self.mapcache[2].get(f) |
118 return self.mapcache[1].get(f), self.mapcache[1].flags(f) |
111 text = self.revision(node) |
119 text = self.revision(node) |
112 start, end = self._search(text, f) |
120 start, end = self._search(text, f) |
113 if start == end: |
121 if start == end: |
114 return None, None |
122 return None, None |
115 l = text[start:end] |
123 l = text[start:end] |