comparison mercurial/manifest.py @ 2835:a9f5d4149123

Combine manifest dict and flags dict into a single object This gets rid of the need to track two objects and might save memory. This might be faster implemented as a subclassed dict with auxiliary functions to access a sparse flags dict.
author Matt Mackall <mpm@selenic.com>
date Wed, 09 Aug 2006 14:53:03 -0500
parents 35af2e56f15a
children b4f05ecf4ee8
comparison
equal deleted inserted replaced
2834:35af2e56f15a 2835:a9f5d4149123
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]
199 cachedelta = None 207 cachedelta = None
200 self.listcache = addlist 208 self.listcache = addlist
201 209
202 n = self.addrevision(buffer(self.listcache), transaction, link, p1, \ 210 n = self.addrevision(buffer(self.listcache), transaction, link, p1, \
203 p2, cachedelta) 211 p2, cachedelta)
204 self.mapcache = (n, map, flags) 212 self.mapcache = (n, map)
205 213
206 return n 214 return n