##// END OF EJS Templates
obsolete: introduce a new binary encoding for obsmarkers (version 1)...
Pierre-Yves David -
r22851:97438942 default
parent child Browse files
Show More
@@ -231,10 +231,145 b' def _fm0decodemeta(data):'
231 d[key] = value
231 d[key] = value
232 return d
232 return d
233
233
234 ## Parsing and writing of version "1"
235 #
236 # The header is followed by the markers. Each marker is made of:
237 #
238 # - uint32: total size of the marker (including this field)
239 #
240 # - float64: date in seconds since epoch
241 #
242 # - int16: timezone offset in minutes
243 #
244 # - uint16: a bit field. It is reserved for flags used in common
245 # obsolete marker operations, to avoid repeated decoding of metadata
246 # entries.
247 #
248 # - uint8: number of successors "N", can be zero.
249 #
250 # - uint8: number of parents "P", can be zero.
251 #
252 # 0: parents data stored but no parent,
253 # 1: one parent stored,
254 # 2: two parents stored,
255 # 3: no parent data stored
256 #
257 # - uint8: number of metadata entries M
258 #
259 # - 20 or 32 bytes: precursor changeset identifier.
260 #
261 # - N*(20 or 32) bytes: successors changesets identifiers.
262 #
263 # - P*(20 or 32) bytes: parents of the precursors changesets.
264 #
265 # - M*(uint8, uint8): size of all metadata entries (key and value)
266 #
267 # - remaining bytes: the metadata, each (key, value) pair after the other.
268 _fm1version = 1
269 _fm1fixed = '>IdhHBBB20s'
270 _fm1nodesha1 = '20s'
271 _fm1nodesha256 = '32s'
272 _fm1fsize = struct.calcsize(_fm1fixed)
273 _fm1parentnone = 3
274 _fm1parentshift = 14
275 _fm1parentmask = (_fm1parentnone << _fm1parentshift)
276 _fm1metapair = 'BB'
277 _fm1metapairsize = struct.calcsize('BB')
278
279 def _fm1readmarkers(data, off=0):
280 # Loop on markers
281 l = len(data)
282 while off + _fm1fsize <= l:
283 # read fixed part
284 cur = data[off:off + _fm1fsize]
285 off += _fm1fsize
286 fixeddata = _unpack(_fm1fixed, cur)
287 ttsize, seconds, tz, flags, numsuc, numpar, nummeta, prec = fixeddata
288 # extract the number of parents information
289 if numpar == _fm1parentnone:
290 numpar = None
291 # build the date tuple (upgrade tz minutes to seconds)
292 date = (seconds, tz * 60)
293 _fm1node = _fm1nodesha1
294 if flags & usingsha256:
295 _fm1node = _fm1nodesha256
296 fnodesize = struct.calcsize(_fm1node)
297 # read replacement
298 sucs = ()
299 if numsuc:
300 s = (fnodesize * numsuc)
301 cur = data[off:off + s]
302 sucs = _unpack(_fm1node * numsuc, cur)
303 off += s
304 # read parents
305 if numpar is None:
306 parents = None
307 elif numpar == 0:
308 parents = ()
309 elif numpar: # neither None nor zero
310 s = (fnodesize * numpar)
311 cur = data[off:off + s]
312 parents = _unpack(_fm1node * numpar, cur)
313 off += s
314 # read metadata
315 metaformat = '>' + (_fm1metapair * nummeta)
316 s = _fm1metapairsize * nummeta
317 metapairsize = _unpack(metaformat, data[off:off + s])
318 off += s
319 metadata = []
320 for idx in xrange(0, len(metapairsize), 2):
321 sk = metapairsize[idx]
322 sv = metapairsize[idx + 1]
323 key = data[off:off + sk]
324 value = data[off + sk:off + sk + sv]
325 assert len(key) == sk
326 assert len(value) == sv
327 metadata.append((key, value))
328 off += sk + sv
329 metadata = tuple(metadata)
330
331 yield (prec, sucs, flags, metadata, date, parents)
332
333 def _fm1encodeonemarker(marker):
334 pre, sucs, flags, metadata, date, parents = marker
335 # determine node size
336 _fm1node = _fm1nodesha1
337 if flags & usingsha256:
338 _fm1node = _fm1nodesha256
339 numsuc = len(sucs)
340 numextranodes = numsuc
341 if parents is None:
342 numpar = _fm1parentnone
343 else:
344 numpar = len(parents)
345 numextranodes += numpar
346 formatnodes = _fm1node * numextranodes
347 formatmeta = _fm1metapair * len(metadata)
348 format = _fm1fixed + formatnodes + formatmeta
349 # tz is stored in minutes so we divide by 60
350 tz = date[1]//60
351 data = [None, date[0], tz, flags, numsuc, numpar, len(metadata), pre]
352 data.extend(sucs)
353 if parents is not None:
354 data.extend(parents)
355 totalsize = struct.calcsize(format)
356 for key, value in metadata:
357 lk = len(key)
358 lv = len(value)
359 data.append(lk)
360 data.append(lv)
361 totalsize += lk + lv
362 data[0] = totalsize
363 data = [_pack(format, *data)]
364 for key, value in metadata:
365 data.append(key)
366 data.append(value)
367 return ''.join(data)
234
368
235 # mapping to read/write various marker formats
369 # mapping to read/write various marker formats
236 # <version> -> (decoder, encoder)
370 # <version> -> (decoder, encoder)
237 formats = {_fm0version: (_fm0readmarkers, _fm0encodeonemarker)}
371 formats = {_fm0version: (_fm0readmarkers, _fm0encodeonemarker),
372 _fm1version: (_fm1readmarkers, _fm1encodeonemarker)}
238
373
239 def _readmarkers(data):
374 def _readmarkers(data):
240 """Read and enumerate markers from raw data"""
375 """Read and enumerate markers from raw data"""
General Comments 0
You need to be logged in to leave comments. Login now