Show More
@@ -27,6 +27,7 b' from .utils import (' | |||||
27 | from .revlogutils import ( |
|
27 | from .revlogutils import ( | |
28 | constants as revlog_constants, |
|
28 | constants as revlog_constants, | |
29 | flagutil, |
|
29 | flagutil, | |
|
30 | randomaccessfile, | |||
30 | ) |
|
31 | ) | |
31 |
|
32 | |||
32 | _defaultextra = {b'branch': b'default'} |
|
33 | _defaultextra = {b'branch': b'default'} | |
@@ -91,76 +92,6 b' def stripdesc(desc):' | |||||
91 | return b'\n'.join([l.rstrip() for l in desc.splitlines()]).strip(b'\n') |
|
92 | return b'\n'.join([l.rstrip() for l in desc.splitlines()]).strip(b'\n') | |
92 |
|
93 | |||
93 |
|
94 | |||
94 | class appender: |
|
|||
95 | """the changelog index must be updated last on disk, so we use this class |
|
|||
96 | to delay writes to it""" |
|
|||
97 |
|
||||
98 | def __init__(self, vfs, name, mode, buf): |
|
|||
99 | self.data = buf |
|
|||
100 | fp = vfs(name, mode) |
|
|||
101 | self.fp = fp |
|
|||
102 | self.offset = fp.tell() |
|
|||
103 | self.size = vfs.fstat(fp).st_size |
|
|||
104 | self._end = self.size |
|
|||
105 |
|
||||
106 | def end(self): |
|
|||
107 | return self._end |
|
|||
108 |
|
||||
109 | def tell(self): |
|
|||
110 | return self.offset |
|
|||
111 |
|
||||
112 | def flush(self): |
|
|||
113 | pass |
|
|||
114 |
|
||||
115 | @property |
|
|||
116 | def closed(self): |
|
|||
117 | return self.fp.closed |
|
|||
118 |
|
||||
119 | def close(self): |
|
|||
120 | self.fp.close() |
|
|||
121 |
|
||||
122 | def seek(self, offset, whence=0): |
|
|||
123 | '''virtual file offset spans real file and data''' |
|
|||
124 | if whence == 0: |
|
|||
125 | self.offset = offset |
|
|||
126 | elif whence == 1: |
|
|||
127 | self.offset += offset |
|
|||
128 | elif whence == 2: |
|
|||
129 | self.offset = self.end() + offset |
|
|||
130 | if self.offset < self.size: |
|
|||
131 | self.fp.seek(self.offset) |
|
|||
132 |
|
||||
133 | def read(self, count=-1): |
|
|||
134 | '''only trick here is reads that span real file and data''' |
|
|||
135 | ret = b"" |
|
|||
136 | if self.offset < self.size: |
|
|||
137 | s = self.fp.read(count) |
|
|||
138 | ret = s |
|
|||
139 | self.offset += len(s) |
|
|||
140 | if count > 0: |
|
|||
141 | count -= len(s) |
|
|||
142 | if count != 0: |
|
|||
143 | doff = self.offset - self.size |
|
|||
144 | self.data.insert(0, b"".join(self.data)) |
|
|||
145 | del self.data[1:] |
|
|||
146 | s = self.data[0][doff : doff + count] |
|
|||
147 | self.offset += len(s) |
|
|||
148 | ret += s |
|
|||
149 | return ret |
|
|||
150 |
|
||||
151 | def write(self, s): |
|
|||
152 | self.data.append(bytes(s)) |
|
|||
153 | self.offset += len(s) |
|
|||
154 | self._end += len(s) |
|
|||
155 |
|
||||
156 | def __enter__(self): |
|
|||
157 | self.fp.__enter__() |
|
|||
158 | return self |
|
|||
159 |
|
||||
160 | def __exit__(self, *args): |
|
|||
161 | return self.fp.__exit__(*args) |
|
|||
162 |
|
||||
163 |
|
||||
164 | class _divertopener: |
|
95 | class _divertopener: | |
165 | def __init__(self, opener, target): |
|
96 | def __init__(self, opener, target): | |
166 | self._opener = opener |
|
97 | self._opener = opener | |
@@ -187,7 +118,7 b' class _delayopener:' | |||||
187 | if name != self._target: |
|
118 | if name != self._target: | |
188 | return self._opener(name, mode, **kwargs) |
|
119 | return self._opener(name, mode, **kwargs) | |
189 | assert not kwargs |
|
120 | assert not kwargs | |
190 | return appender(self._opener, name, mode, self._buf) |
|
121 | return randomaccessfile.appender(self._opener, name, mode, self._buf) | |
191 |
|
122 | |||
192 | def __getattr__(self, attr): |
|
123 | def __getattr__(self, attr): | |
193 | return getattr(self._opener, attr) |
|
124 | return getattr(self._opener, attr) |
@@ -23,6 +23,76 b' def _is_power_of_two(n):' | |||||
23 | return (n & (n - 1) == 0) and n != 0 |
|
23 | return (n & (n - 1) == 0) and n != 0 | |
24 |
|
24 | |||
25 |
|
25 | |||
|
26 | class appender: | |||
|
27 | """the changelog index must be updated last on disk, so we use this class | |||
|
28 | to delay writes to it""" | |||
|
29 | ||||
|
30 | def __init__(self, vfs, name, mode, buf): | |||
|
31 | self.data = buf | |||
|
32 | fp = vfs(name, mode) | |||
|
33 | self.fp = fp | |||
|
34 | self.offset = fp.tell() | |||
|
35 | self.size = vfs.fstat(fp).st_size | |||
|
36 | self._end = self.size | |||
|
37 | ||||
|
38 | def end(self): | |||
|
39 | return self._end | |||
|
40 | ||||
|
41 | def tell(self): | |||
|
42 | return self.offset | |||
|
43 | ||||
|
44 | def flush(self): | |||
|
45 | pass | |||
|
46 | ||||
|
47 | @property | |||
|
48 | def closed(self): | |||
|
49 | return self.fp.closed | |||
|
50 | ||||
|
51 | def close(self): | |||
|
52 | self.fp.close() | |||
|
53 | ||||
|
54 | def seek(self, offset, whence=0): | |||
|
55 | '''virtual file offset spans real file and data''' | |||
|
56 | if whence == 0: | |||
|
57 | self.offset = offset | |||
|
58 | elif whence == 1: | |||
|
59 | self.offset += offset | |||
|
60 | elif whence == 2: | |||
|
61 | self.offset = self.end() + offset | |||
|
62 | if self.offset < self.size: | |||
|
63 | self.fp.seek(self.offset) | |||
|
64 | ||||
|
65 | def read(self, count=-1): | |||
|
66 | '''only trick here is reads that span real file and data''' | |||
|
67 | ret = b"" | |||
|
68 | if self.offset < self.size: | |||
|
69 | s = self.fp.read(count) | |||
|
70 | ret = s | |||
|
71 | self.offset += len(s) | |||
|
72 | if count > 0: | |||
|
73 | count -= len(s) | |||
|
74 | if count != 0: | |||
|
75 | doff = self.offset - self.size | |||
|
76 | self.data.insert(0, b"".join(self.data)) | |||
|
77 | del self.data[1:] | |||
|
78 | s = self.data[0][doff : doff + count] | |||
|
79 | self.offset += len(s) | |||
|
80 | ret += s | |||
|
81 | return ret | |||
|
82 | ||||
|
83 | def write(self, s): | |||
|
84 | self.data.append(bytes(s)) | |||
|
85 | self.offset += len(s) | |||
|
86 | self._end += len(s) | |||
|
87 | ||||
|
88 | def __enter__(self): | |||
|
89 | self.fp.__enter__() | |||
|
90 | return self | |||
|
91 | ||||
|
92 | def __exit__(self, *args): | |||
|
93 | return self.fp.__exit__(*args) | |||
|
94 | ||||
|
95 | ||||
26 | class randomaccessfile: |
|
96 | class randomaccessfile: | |
27 | """Accessing arbitrary chuncks of data within a file, with some caching""" |
|
97 | """Accessing arbitrary chuncks of data within a file, with some caching""" | |
28 |
|
98 |
General Comments 0
You need to be logged in to leave comments.
Login now