23 # code outside this module should always use dirstatetuple. |
23 # code outside this module should always use dirstatetuple. |
24 def dirstatetuple(*x): |
24 def dirstatetuple(*x): |
25 # x is a tuple |
25 # x is a tuple |
26 return x |
26 return x |
27 |
27 |
|
28 indexformatng = ">Qiiiiii20s12x" |
|
29 indexfirst = struct.calcsize('Q') |
|
30 sizeint = struct.calcsize('i') |
|
31 indexsize = struct.calcsize(indexformatng) |
|
32 |
|
33 def gettype(q): |
|
34 return int(q & 0xFFFF) |
|
35 |
|
36 def offset_type(offset, type): |
|
37 return long(long(offset) << 16 | type) |
|
38 |
|
39 class BaseIndexObject(object): |
|
40 def __len__(self): |
|
41 return self._lgt + len(self._extra) + 1 |
|
42 |
|
43 def insert(self, i, tup): |
|
44 assert i == -1 |
|
45 self._extra.append(tup) |
|
46 |
|
47 def _fix_index(self, i): |
|
48 if not isinstance(i, int): |
|
49 raise TypeError("expecting int indexes") |
|
50 if i < 0: |
|
51 i = len(self) + i |
|
52 if i < 0 or i >= len(self): |
|
53 raise IndexError |
|
54 return i |
|
55 |
|
56 def __getitem__(self, i): |
|
57 i = self._fix_index(i) |
|
58 if i == len(self) - 1: |
|
59 return (0, 0, 0, -1, -1, -1, -1, nullid) |
|
60 if i >= self._lgt: |
|
61 return self._extra[i - self._lgt] |
|
62 index = self._calculate_index(i) |
|
63 r = struct.unpack(indexformatng, self._data[index:index + indexsize]) |
|
64 if i == 0: |
|
65 e = list(r) |
|
66 type = gettype(e[0]) |
|
67 e[0] = offset_type(0, type) |
|
68 return tuple(e) |
|
69 return r |
|
70 |
|
71 class IndexObject(BaseIndexObject): |
|
72 def __init__(self, data): |
|
73 assert len(data) % indexsize == 0 |
|
74 self._data = data |
|
75 self._lgt = len(data) // indexsize |
|
76 self._extra = [] |
|
77 |
|
78 def _calculate_index(self, i): |
|
79 return i * indexsize |
|
80 |
|
81 def __delitem__(self, i): |
|
82 if not isinstance(i, slice) or not i.stop == -1 or not i.step is None: |
|
83 raise ValueError("deleting slices only supports a:-1 with step 1") |
|
84 i = self._fix_index(i.start) |
|
85 if i < self._lgt: |
|
86 self._data = self._data[:i * indexsize] |
|
87 self._lgt = i |
|
88 self._extra = [] |
|
89 else: |
|
90 self._extra = self._extra[:i - self._lgt] |
|
91 |
|
92 class InlinedIndexObject(BaseIndexObject): |
|
93 def __init__(self, data, inline=0): |
|
94 self._data = data |
|
95 self._lgt = self._inline_scan(None) |
|
96 self._inline_scan(self._lgt) |
|
97 self._extra = [] |
|
98 |
|
99 def _inline_scan(self, lgt): |
|
100 off = 0 |
|
101 if lgt is not None: |
|
102 self._offsets = [0] * lgt |
|
103 count = 0 |
|
104 while off <= len(self._data) - indexsize: |
|
105 s, = struct.unpack('>i', |
|
106 self._data[off + indexfirst:off + sizeint + indexfirst]) |
|
107 if lgt is not None: |
|
108 self._offsets[count] = off |
|
109 count += 1 |
|
110 off += indexsize + s |
|
111 if off != len(self._data): |
|
112 raise ValueError("corrupted data") |
|
113 return count |
|
114 |
|
115 def __delitem__(self, i): |
|
116 if not isinstance(i, slice) or not i.stop == -1 or not i.step is None: |
|
117 raise ValueError("deleting slices only supports a:-1 with step 1") |
|
118 i = self._fix_index(i.start) |
|
119 if i < self._lgt: |
|
120 self._offsets = self._offsets[:i] |
|
121 self._lgt = i |
|
122 self._extra = [] |
|
123 else: |
|
124 self._extra = self._extra[:i - self._lgt] |
|
125 |
|
126 def _calculate_index(self, i): |
|
127 return self._offsets[i] |
|
128 |
28 def parse_index2(data, inline): |
129 def parse_index2(data, inline): |
29 def gettype(q): |
130 if not inline: |
30 return int(q & 0xFFFF) |
131 return IndexObject(data), None |
31 |
132 return InlinedIndexObject(data, inline), (0, data) |
32 def offset_type(offset, type): |
|
33 return long(long(offset) << 16 | type) |
|
34 |
|
35 indexformatng = ">Qiiiiii20s12x" |
|
36 |
|
37 s = struct.calcsize(indexformatng) |
|
38 index = [] |
|
39 cache = None |
|
40 off = 0 |
|
41 |
|
42 l = len(data) - s |
|
43 append = index.append |
|
44 if inline: |
|
45 cache = (0, data) |
|
46 while off <= l: |
|
47 e = _unpack(indexformatng, data[off:off + s]) |
|
48 append(e) |
|
49 if e[1] < 0: |
|
50 break |
|
51 off += e[1] + s |
|
52 else: |
|
53 while off <= l: |
|
54 e = _unpack(indexformatng, data[off:off + s]) |
|
55 append(e) |
|
56 off += s |
|
57 |
|
58 if off != len(data): |
|
59 raise ValueError('corrupt index file') |
|
60 |
|
61 if index: |
|
62 e = list(index[0]) |
|
63 type = gettype(e[0]) |
|
64 e[0] = offset_type(0, type) |
|
65 index[0] = tuple(e) |
|
66 |
|
67 # add the magic null revision at -1 |
|
68 index.append((0, 0, 0, -1, -1, -1, -1, nullid)) |
|
69 |
|
70 return index, cache |
|
71 |
133 |
72 def parse_dirstate(dmap, copymap, st): |
134 def parse_dirstate(dmap, copymap, st): |
73 parents = [st[:20], st[20: 40]] |
135 parents = [st[:20], st[20: 40]] |
74 # dereference fields so they will be local in loop |
136 # dereference fields so they will be local in loop |
75 format = ">cllll" |
137 format = ">cllll" |