Patchwork [8,of,8] obsmarker: add `date` as an explicit field

login
register
mail settings
Submitter Pierre-Yves David
Date Aug. 16, 2014, 12:33 a.m.
Message ID <aaca3cffab4c0df9191a.1408149210@marginatus.alto.octopoid.net>
Download mbox | patch
Permalink /patch/5444/
State Accepted
Headers show

Comments

Pierre-Yves David - Aug. 16, 2014, 12:33 a.m.
# HG changeset patch
# User Pierre-Yves David <pierre-yves.david@fb.com>
# Date 1407998360 25200
#      Wed Aug 13 23:39:20 2014 -0700
# Node ID aaca3cffab4c0df9191aabc07e61a6e6f34334d5
# Parent  79d3a254de51f80fc32888db2465cf38350a4773
obsmarker: add `date` as an explicit field

The marker are now a 5 items tuples (concluded by the date). The obsstore.fields
content have been updated accordingly.

There is now change to the on disk format yet, so the date has to be extracted
every time we read binary markers and re-injected each team we write them. This
introduce a slow down that will be solved when a new version of the format will
be added. Such slowdown was already introduced by the evolve extension anyway.
Augie Fackler - Aug. 18, 2014, 10:43 p.m.
On Fri, Aug 15, 2014 at 05:33:30PM -0700, Pierre-Yves David wrote:
> # HG changeset patch
> # User Pierre-Yves David <pierre-yves.david@fb.com>
> # Date 1407998360 25200
> #      Wed Aug 13 23:39:20 2014 -0700
> # Node ID aaca3cffab4c0df9191aabc07e61a6e6f34334d5
> # Parent  79d3a254de51f80fc32888db2465cf38350a4773
> obsmarker: add `date` as an explicit field

Looks good, queued.

>
> The marker are now a 5 items tuples (concluded by the date). The obsstore.fields
> content have been updated accordingly.
>
> There is now change to the on disk format yet, so the date has to be extracted
> every time we read binary markers and re-injected each team we write them. This
> introduce a slow down that will be solved when a new version of the format will
> be added. Such slowdown was already introduced by the evolve extension anyway.
>
> diff --git a/mercurial/obsolete.py b/mercurial/obsolete.py
> --- a/mercurial/obsolete.py
> +++ b/mercurial/obsolete.py
> @@ -166,11 +166,13 @@ def _readmarkers(data):
>          if len(metadata) != mdsize:
>              raise util.Abort(_('parsing obsolete marker: metadata is too '
>                                 'short, %d bytes expected, got %d')
>                               % (mdsize, len(metadata)))
>          off += mdsize
> -        yield (pre, sucs, flags, metadata)
> +        date = util.parsedate(decodemeta(metadata).pop('date', '0 0'))
> +
> +        yield (pre, sucs, flags, metadata, date)
>
>  def encodemeta(meta):
>      """Return encoded metadata string to string mapping.
>
>      Assume no ':' in key and no '\0' in both key and value."""
> @@ -221,12 +223,11 @@ class marker(object):
>              self._decodedmeta = decodemeta(self._data[3])
>          return self._decodedmeta
>
>      def date(self):
>          """Creation date as (unixtime, offset)"""
> -        parts = self.metadata()['date'].split(' ')
> -        return (float(parts[0]), int(parts[1]))
> +        return self._data[4]
>
>      def flags(self):
>          """The flags field of the marker"""
>          return self._data[2]
>
> @@ -236,11 +237,11 @@ class obsstore(object):
>      Markers can be accessed with two mappings:
>      - precursors[x] -> set(markers on precursors edges of x)
>      - successors[x] -> set(markers on successors edges of x)
>      """
>
> -    fields = ('prec', 'succs', 'flag', 'meta')
> +    fields = ('prec', 'succs', 'flag', 'meta', 'date')
>
>      def __init__(self, sopener):
>          # caches for various obsolescence related cache
>          self.caches = {}
>          self._all = []
> @@ -275,22 +276,25 @@ class obsstore(object):
>          return True if a new marker have been added, False if the markers
>          already existed (no op).
>          """
>          if metadata is None:
>              metadata = {}
> -        if 'date' not in metadata:
> -            if date is None:
> +        if date is None:
> +            if 'date' in metadata:
> +                # by courtesies for out of tree extension
> +                date = util.parsedate(metadata.pop('date'))
> +            else:
>                  date = util.makedate()
> -            metadata['date'] = "%d %d" % date
>          if len(prec) != 20:
>              raise ValueError(prec)
>          for succ in succs:
>              if len(succ) != 20:
>                  raise ValueError(succ)
>          if prec in succs:
>              raise ValueError(_('in-marker cycle with %s') % node.hex(prec))
> -        marker = (str(prec), tuple(succs), int(flag), encodemeta(metadata))
> +        marker = (str(prec), tuple(succs), int(flag), encodemeta(metadata),
> +                  date)
>          return bool(self.add(transaction, [marker]))
>
>      def add(self, transaction, markers):
>          """Add new markers to the store
>
> @@ -350,11 +354,14 @@ def _encodemarkers(markers, addheader=Fa
>      for marker in markers:
>          yield _encodeonemarker(marker)
>
>
>  def _encodeonemarker(marker):
> -    pre, sucs, flags, metadata = marker
> +    pre, sucs, flags, metadata, date = marker
> +    metadata = decodemeta(metadata)
> +    metadata['date'] = '%d %i' % date
> +    metadata = encodemeta(metadata)
>      nbsuc = len(sucs)
>      format = _fmfixed + (_fmnode * nbsuc)
>      data = [nbsuc, len(metadata), flags, pre]
>      data.extend(sucs)
>      return _pack(format, *data) + metadata
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel@selenic.com
> http://selenic.com/mailman/listinfo/mercurial-devel

Patch

diff --git a/mercurial/obsolete.py b/mercurial/obsolete.py
--- a/mercurial/obsolete.py
+++ b/mercurial/obsolete.py
@@ -166,11 +166,13 @@  def _readmarkers(data):
         if len(metadata) != mdsize:
             raise util.Abort(_('parsing obsolete marker: metadata is too '
                                'short, %d bytes expected, got %d')
                              % (mdsize, len(metadata)))
         off += mdsize
-        yield (pre, sucs, flags, metadata)
+        date = util.parsedate(decodemeta(metadata).pop('date', '0 0'))
+
+        yield (pre, sucs, flags, metadata, date)
 
 def encodemeta(meta):
     """Return encoded metadata string to string mapping.
 
     Assume no ':' in key and no '\0' in both key and value."""
@@ -221,12 +223,11 @@  class marker(object):
             self._decodedmeta = decodemeta(self._data[3])
         return self._decodedmeta
 
     def date(self):
         """Creation date as (unixtime, offset)"""
-        parts = self.metadata()['date'].split(' ')
-        return (float(parts[0]), int(parts[1]))
+        return self._data[4]
 
     def flags(self):
         """The flags field of the marker"""
         return self._data[2]
 
@@ -236,11 +237,11 @@  class obsstore(object):
     Markers can be accessed with two mappings:
     - precursors[x] -> set(markers on precursors edges of x)
     - successors[x] -> set(markers on successors edges of x)
     """
 
-    fields = ('prec', 'succs', 'flag', 'meta')
+    fields = ('prec', 'succs', 'flag', 'meta', 'date')
 
     def __init__(self, sopener):
         # caches for various obsolescence related cache
         self.caches = {}
         self._all = []
@@ -275,22 +276,25 @@  class obsstore(object):
         return True if a new marker have been added, False if the markers
         already existed (no op).
         """
         if metadata is None:
             metadata = {}
-        if 'date' not in metadata:
-            if date is None:
+        if date is None:
+            if 'date' in metadata:
+                # by courtesies for out of tree extension
+                date = util.parsedate(metadata.pop('date'))
+            else:
                 date = util.makedate()
-            metadata['date'] = "%d %d" % date
         if len(prec) != 20:
             raise ValueError(prec)
         for succ in succs:
             if len(succ) != 20:
                 raise ValueError(succ)
         if prec in succs:
             raise ValueError(_('in-marker cycle with %s') % node.hex(prec))
-        marker = (str(prec), tuple(succs), int(flag), encodemeta(metadata))
+        marker = (str(prec), tuple(succs), int(flag), encodemeta(metadata),
+                  date)
         return bool(self.add(transaction, [marker]))
 
     def add(self, transaction, markers):
         """Add new markers to the store
 
@@ -350,11 +354,14 @@  def _encodemarkers(markers, addheader=Fa
     for marker in markers:
         yield _encodeonemarker(marker)
 
 
 def _encodeonemarker(marker):
-    pre, sucs, flags, metadata = marker
+    pre, sucs, flags, metadata, date = marker
+    metadata = decodemeta(metadata)
+    metadata['date'] = '%d %i' % date
+    metadata = encodemeta(metadata)
     nbsuc = len(sucs)
     format = _fmfixed + (_fmnode * nbsuc)
     data = [nbsuc, len(metadata), flags, pre]
     data.extend(sucs)
     return _pack(format, *data) + metadata