All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sage Weil <sage@newdream.net>
To: Yehuda Sadeh-Weinraub <yehuda@redhat.com>
Cc: ceph-devel <ceph-devel@vger.kernel.org>
Subject: Re: divergent datastructure changes
Date: Thu, 25 Aug 2016 21:32:09 +0000 (UTC)	[thread overview]
Message-ID: <alpine.DEB.2.11.1608252128560.25681@piezo.us.to> (raw)
In-Reply-To: <CADRKj5R=dnq6xxGvizTB-_jqfPWaCXnkFCkMsz4_ePppyo8HCQ@mail.gmail.com>

On Thu, 25 Aug 2016, Yehuda Sadeh-Weinraub wrote:
> The encode/decode functionality that we use for [de]marshalling is
> fine, as long as we always move forward. Here's a typical example
> (redacted for simplicity).
> 
>   void encode(bufferlist& bl) const {
>     ENCODE_START(8, 1, bl);
>     ::encode(domain_root, bl);
>     ::encode(control_pool, bl);
>     ::encode(gc_pool, bl);
>     ::encode(log_pool, bl);
>     ::encode(intent_log_pool, bl);
>     ::encode(usage_log_pool, bl);
>     ::encode(user_keys_pool, bl);
>     ::encode(user_email_pool, bl);
>     ::encode(user_swift_pool, bl);
>     ::encode(user_uid_pool, bl);
> ...
>     ::encode(system_key, bl);
>     ::encode(placement_pools, bl);
>     ::encode(metadata_heap, bl);
>     ::encode(realm_id, bl);
> ...
>     ENCODE_FINISH(bl);
>   }
> 
>   void decode(bufferlist::iterator& bl) {
>     DECODE_START(8, bl);
>     ::decode(domain_root, bl);
>     ::decode(control_pool, bl);
>     ::decode(gc_pool, bl);
>     ::decode(log_pool, bl);
>     ::decode(intent_log_pool, bl);
>     ::decode(usage_log_pool, bl);
>     ::decode(user_keys_pool, bl);
>     ::decode(user_email_pool, bl);
>     ::decode(user_swift_pool, bl);
>     ::decode(user_uid_pool, bl);
> ...
>     if (struct_v >= 3)
>       ::decode(system_key, bl);
>     if (struct_v >= 4)
>       ::decode(placement_pools, bl);
>     if (struct_v >= 5)
>       ::decode(metadata_heap, bl);
>     if (struct_v >= 6) {
>       ::decode(realm_id, bl);
>     }
> ...
>     DECODE_FINISH(bl);
>   }
> 
> So the idea is that whenever we add a field, we bump up the encoded
> version, add the field at the end. Decoding is done in order, and we
> test struct_v to determine whether we need to decode the next param.
> 
> The main issue I'm having trouble with right now is what to do when we
> need to backport a change that needs a datastructure change. For
> example. in the above example, let's say that we need to backport the
> realm_id field to an older version that was only up to V3.
> 
> One solution would be to make sure that when backporting such a
> change, we need to drag with us all the other fields that lead up to
> to the one that we need (e.g., we want realm_id, but we need to bring
> with us also placement_pools, and metadata_heap). This might not be so
> sustainable. The above example might be trivial, but what if
> metadata_heap was not a string, but rather a complex data type that in
> order to build correctly, we need to backport another feature (and
> bring with it the same issues).

In the past we've just dragged the other fields with us.  I can only 
recall this happening a handful of times.  I try to put any new fields 
into a separate commit with *just* the data structure changes so that 
(among other things) it can be easily backported without dragging anything 
else along with it.
 
> It seems to me that for issues like that we might want to consider
> adding a more sophisticated encoding scheme that will be more feature
> oriented, rather than just blindly putting everything one after the
> other.
> 
> E.g., some kind of a bit field with offsets into the data, along the
> following lines:
> 
> feature.encode(0, system_key);
> feature.encode(1, placement_pools);
> feature.encode(2, metadata_heap);
> ::encode(features, bl);
> 
> and on the decoding side:
> 
> ::decode(features, bl);
> features.decode(0, system_key);
> features.decode(1, placement_pools);
> features.decode(2, metadata_heap);
> 
> In the above example, if we only need metadata_heap, then we can just do this:
> 
> ::decode(features, bl);
> features.decode(2, metadata_heap);
> 
> The indexes to the fields should be defined appropriately obviously,
> and will be consistent across versions. That should be relatively
> easier to maintain than making sure we keep the data structures
> consistent when having divergent branches I think.

This seems useful if we need to backport things out of order, but how 
often does that really happen?  The cost is some CPU time during decoding, 
incurred for every encode/decode for all time, to cover a case that should 
be pretty rare.

Have we need a case where the intervening fields are complex data 
structure(s) and difficult to backport?

sage

  reply	other threads:[~2016-08-25 21:38 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-08-25 21:10 divergent datastructure changes Yehuda Sadeh-Weinraub
2016-08-25 21:32 ` Sage Weil [this message]
2016-08-25 21:59   ` Yehuda Sadeh-Weinraub
2016-08-25 22:04     ` Mark Nelson
2016-08-25 22:20       ` Yehuda Sadeh-Weinraub
2016-08-25 21:41 ` Gregory Farnum

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=alpine.DEB.2.11.1608252128560.25681@piezo.us.to \
    --to=sage@newdream.net \
    --cc=ceph-devel@vger.kernel.org \
    --cc=yehuda@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.