166 if len(metadata) != mdsize: |
166 if len(metadata) != mdsize: |
167 raise util.Abort(_('parsing obsolete marker: metadata is too ' |
167 raise util.Abort(_('parsing obsolete marker: metadata is too ' |
168 'short, %d bytes expected, got %d') |
168 'short, %d bytes expected, got %d') |
169 % (mdsize, len(metadata))) |
169 % (mdsize, len(metadata))) |
170 off += mdsize |
170 off += mdsize |
171 yield (pre, sucs, flags, metadata) |
171 try: |
|
172 date = util.parsedate(decodemeta(metadata).pop('date', '0 0')) |
|
173 except util.Abort: |
|
174 date = (0., 0) |
|
175 |
|
176 yield (pre, sucs, flags, metadata, date) |
172 |
177 |
173 def encodemeta(meta): |
178 def encodemeta(meta): |
174 """Return encoded metadata string to string mapping. |
179 """Return encoded metadata string to string mapping. |
175 |
180 |
176 Assume no ':' in key and no '\0' in both key and value.""" |
181 Assume no ':' in key and no '\0' in both key and value.""" |
221 self._decodedmeta = decodemeta(self._data[3]) |
226 self._decodedmeta = decodemeta(self._data[3]) |
222 return self._decodedmeta |
227 return self._decodedmeta |
223 |
228 |
224 def date(self): |
229 def date(self): |
225 """Creation date as (unixtime, offset)""" |
230 """Creation date as (unixtime, offset)""" |
226 parts = self.metadata()['date'].split(' ') |
231 return self._data[4] |
227 return (float(parts[0]), int(parts[1])) |
|
228 |
232 |
229 def flags(self): |
233 def flags(self): |
230 """The flags field of the marker""" |
234 """The flags field of the marker""" |
231 return self._data[2] |
235 return self._data[2] |
232 |
236 |
236 Markers can be accessed with two mappings: |
240 Markers can be accessed with two mappings: |
237 - precursors[x] -> set(markers on precursors edges of x) |
241 - precursors[x] -> set(markers on precursors edges of x) |
238 - successors[x] -> set(markers on successors edges of x) |
242 - successors[x] -> set(markers on successors edges of x) |
239 """ |
243 """ |
240 |
244 |
241 fields = ('prec', 'succs', 'flag', 'meta') |
245 fields = ('prec', 'succs', 'flag', 'meta', 'date') |
242 |
246 |
243 def __init__(self, sopener): |
247 def __init__(self, sopener): |
244 # caches for various obsolescence related cache |
248 # caches for various obsolescence related cache |
245 self.caches = {} |
249 self.caches = {} |
246 self._all = [] |
250 self._all = [] |
275 return True if a new marker have been added, False if the markers |
279 return True if a new marker have been added, False if the markers |
276 already existed (no op). |
280 already existed (no op). |
277 """ |
281 """ |
278 if metadata is None: |
282 if metadata is None: |
279 metadata = {} |
283 metadata = {} |
280 if 'date' not in metadata: |
284 if date is None: |
281 if date is None: |
285 if 'date' in metadata: |
|
286 # as a courtesy for out-of-tree extensions |
|
287 date = util.parsedate(metadata.pop('date')) |
|
288 else: |
282 date = util.makedate() |
289 date = util.makedate() |
283 metadata['date'] = "%d %d" % date |
|
284 if len(prec) != 20: |
290 if len(prec) != 20: |
285 raise ValueError(prec) |
291 raise ValueError(prec) |
286 for succ in succs: |
292 for succ in succs: |
287 if len(succ) != 20: |
293 if len(succ) != 20: |
288 raise ValueError(succ) |
294 raise ValueError(succ) |
289 if prec in succs: |
295 if prec in succs: |
290 raise ValueError(_('in-marker cycle with %s') % node.hex(prec)) |
296 raise ValueError(_('in-marker cycle with %s') % node.hex(prec)) |
291 marker = (str(prec), tuple(succs), int(flag), encodemeta(metadata)) |
297 marker = (str(prec), tuple(succs), int(flag), encodemeta(metadata), |
|
298 date) |
292 return bool(self.add(transaction, [marker])) |
299 return bool(self.add(transaction, [marker])) |
293 |
300 |
294 def add(self, transaction, markers): |
301 def add(self, transaction, markers): |
295 """Add new markers to the store |
302 """Add new markers to the store |
296 |
303 |
350 for marker in markers: |
357 for marker in markers: |
351 yield _encodeonemarker(marker) |
358 yield _encodeonemarker(marker) |
352 |
359 |
353 |
360 |
354 def _encodeonemarker(marker): |
361 def _encodeonemarker(marker): |
355 pre, sucs, flags, metadata = marker |
362 pre, sucs, flags, metadata, date = marker |
|
363 metadata = decodemeta(metadata) |
|
364 metadata['date'] = '%d %i' % date |
|
365 metadata = encodemeta(metadata) |
356 nbsuc = len(sucs) |
366 nbsuc = len(sucs) |
357 format = _fmfixed + (_fmnode * nbsuc) |
367 format = _fmfixed + (_fmnode * nbsuc) |
358 data = [nbsuc, len(metadata), flags, pre] |
368 data = [nbsuc, len(metadata), flags, pre] |
359 data.extend(sucs) |
369 data.extend(sucs) |
360 return _pack(format, *data) + metadata |
370 return _pack(format, *data) + metadata |