unofficial mirror of notmuch@notmuchmail.org
 help / color / mirror / code / Atom feed
From: Austin Clements <amdragon@MIT.EDU>
To: Jani Nikula <jani@nikula.org>
Cc: notmuch@notmuchmail.org, dkg@fifthhorseman.net
Subject: Re: [PATCH 1/3] mime node: Record depth-first part numbers
Date: Wed, 18 Jan 2012 21:12:54 -0500	[thread overview]
Message-ID: <20120119021254.GJ16740@mit.edu> (raw)
In-Reply-To: <87zkdkbqc6.fsf@nikula.org>

Quoth Jani Nikula on Jan 19 at 12:25 am:
> On Wed, 18 Jan 2012 15:28:25 -0500, Austin Clements <amdragon@MIT.EDU> wrote:
> > This makes the part numbers readily accessible to formatters.
> > Hierarchical part numbering would be a more natural and efficient fit
> > for MIME and may be the way to go in the future, but depth-first
> > numbering maintains compatibility with what we currently do.
> 
> Hi, please find a few things to consider below. If you disagree after
> considering, it's quite all right, as they're largely style matters. :)
> 
> BR,
> Jani.
> 
> 
> > ---
> >  mime-node.c      |   33 ++++++++++++++++++++++++++++++++-
> >  notmuch-client.h |   11 +++++++++++
> >  2 files changed, 43 insertions(+), 1 deletions(-)
> > 
> > diff --git a/mime-node.c b/mime-node.c
> > index d26bb44..30b542f 100644
> > --- a/mime-node.c
> > +++ b/mime-node.c
> > @@ -104,6 +104,10 @@ mime_node_open (const void *ctx, notmuch_message_t *message,
> >      root->nchildren = 1;
> >      root->ctx = mctx;
> >  
> > +    root->part_num = 0;
> > +    root->next_child = 0;
> > +    root->next_part_num = 1;
> > +
> >      *root_out = root;
> >      return NOTMUCH_STATUS_SUCCESS;
> >  
> > @@ -133,6 +137,8 @@ _mime_node_create (const mime_node_t *parent, GMimeObject *part)
> >  	talloc_free (node);
> >  	return NULL;
> >      }
> > +    node->parent = parent;
> > +    node->part_num = node->next_part_num = -1;
> >  
> >      /* Deal with the different types of parts */
> >      if (GMIME_IS_PART (part)) {
> > @@ -217,6 +223,7 @@ mime_node_t *
> >  mime_node_child (const mime_node_t *parent, int child)
> >  {
> >      GMimeObject *sub;
> > +    mime_node_t *node;
> >  
> >      if (!parent || child < 0 || child >= parent->nchildren)
> >  	return NULL;
> > @@ -234,7 +241,31 @@ mime_node_child (const mime_node_t *parent, int child)
> >  	INTERNAL_ERROR ("Unexpected GMimeObject type: %s",
> >  			g_type_name (G_OBJECT_TYPE (parent->part)));
> >      }
> > -    return _mime_node_create (parent, sub);
> > +    node = _mime_node_create (parent, sub);
> > +
> > +    if (child == parent->next_child && parent->next_part_num != -1) {
> > +	/* We're traversing in depth-first order.  Record the child's
> > +	 * depth-first numbering. */
> > +	node->part_num = parent->next_part_num;
> > +	node->next_part_num = node->part_num + 1;
> > +
> > +	/* Drop the const qualifier because these are internal fields
> > +	 * whose mutability doesn't affect the interface. */
> 
> FWIW, I'm not a big fan of casting away const. Either it is const, or it
> isn't. Not very many places would be affected if you dropped the const
> qualifier from the related interface(s) altogether, and things would
> look cleaner here. But I suppose this is a matter of taste.

I'm not particularly happy with this either.  Unfortunately, dropping
the const here affects a surprising number of places, including the
entire MIME node API.

I think that, at a deep level, depth-first numbering simply doesn't
resonate with an extremely hierarchical API like this and that
dissonance is going to have to focus somewhere.  There have been
discussions of switching to hierarchical part numbering before (in
particular, because depth-first numbering is unstable with encrypted
parts) and I'll probably restart those after all of this is done.

> > +	((mime_node_t*)parent)->next_child++;
> > +	((mime_node_t*)parent)->next_part_num = -1;
> > +
> > +	if (node->nchildren == 0) {
> > +	    /* We've reached a leaf, so find the parent that has more
> > +	     * children and set it up to number its next child. */
> > +	    const mime_node_t *it = node;
> > +	    while (it && it->next_child == it->nchildren)
> > +		it = it->parent;
> > +	    if (it)
> > +		((mime_node_t*)it)->next_part_num = node->part_num + 1;
> > +	}
> > +    }
> 
> Following the constness around made me wonder why the above if block
> isn't within _mime_node_create(). It does have a feel of initialization
> related to creation in it. (You'd have to pass more info to it though.)

I considered this, but was dissuaded by having to pass redundant
information to _mime_node_create.  I think it's okay here because it
has as much to do with child fetching as with initialization, but I
could easily be swayed.

> > +
> > +    return node;
> >  }
> >  
> >  static mime_node_t *
> > diff --git a/notmuch-client.h b/notmuch-client.h
> > index 62ede28..b3dcb6b 100644
> > --- a/notmuch-client.h
> > +++ b/notmuch-client.h
> > @@ -281,6 +281,13 @@ typedef struct mime_node {
> >      /* The number of children of this part. */
> >      int nchildren;
> >  
> > +    /* The parent of this node or NULL if this is the root node. */
> > +    const struct mime_node *parent;
> > +
> > +    /* The depth-first part number of this child if the MIME tree is
> > +     * being traversed in depth-first order, or -1 otherwise. */
> > +    int part_num;
> > +
> >      /* True if decryption of this part was attempted. */
> >      notmuch_bool_t decrypt_attempted;
> >      /* True if decryption of this part's child succeeded.  In this
> > @@ -302,6 +309,10 @@ typedef struct mime_node {
> >      /* Internal: For successfully decrypted multipart parts, the
> >       * decrypted part to substitute for the second child. */
> >      GMimeObject *decrypted_child;
> > +
> > +    /* Internal: The next child for depth-first traversal and the part
> > +     * number to assign it (or -1 if unknown). */
> > +    int next_child, next_part_num;
> 
> A matter of taste again, but I wouldn't use "int foo, bar" in struct
> declarations.

Fixed.

> >  } mime_node_t;
> >  
> >  /* Construct a new MIME node pointing to the root message part of
> 

  reply	other threads:[~2012-01-19  2:13 UTC|newest]

Thread overview: 40+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-01-18 20:28 [PATCH 0/3] Second step of 'show' rewrite Austin Clements
2012-01-18 20:28 ` [PATCH 1/3] mime node: Record depth-first part numbers Austin Clements
2012-01-18 22:25   ` Jani Nikula
2012-01-19  2:12     ` Austin Clements [this message]
2012-01-23  1:02       ` Austin Clements
2012-01-18 20:28 ` [PATCH 2/3] show: Use consistent header ordering in the text format Austin Clements
2012-01-20 13:45   ` Tomi Ollila
2012-01-18 20:28 ` [PATCH 3/3] show: Introduce mime_node formatter callback Austin Clements
2012-01-18 22:33   ` Jani Nikula
2012-01-19  2:23     ` Austin Clements
2012-01-18 20:35 ` [PATCH 0/3] Second step of 'show' rewrite Dmitry Kurochkin
2012-01-18 20:45   ` Austin Clements
2012-01-22 22:44 ` Jameson Graef Rollins
2012-01-23  2:31 ` [PATCH v2 " Austin Clements
2012-01-23  2:31   ` [PATCH v2 1/3] mime node: Record depth-first part numbers Austin Clements
2012-01-23 18:07     ` Jani Nikula
2012-01-23 21:36     ` Tomi Ollila
2012-01-23 22:19     ` Dmitry Kurochkin
2012-01-23 23:15       ` Austin Clements
2012-01-23  2:31   ` [PATCH v2 2/3] show: Use consistent header ordering in the text format Austin Clements
2012-01-23  2:31   ` [PATCH v2 3/3] show: Introduce mime_node formatter callback Austin Clements
2012-01-23 21:00     ` Tomi Ollila
2012-01-23 22:37     ` Dmitry Kurochkin
2012-01-23 23:23       ` Austin Clements
2012-01-23 20:28 ` [PATCH v3 0/2] Second step of 'show' rewrite Austin Clements
2012-01-23 20:29   ` [PATCH v3 1/2] mime node: Record depth-first part numbers Austin Clements
2012-01-23 20:29   ` [PATCH v3 2/2] show: Introduce mime_node formatter callback Austin Clements
2012-01-23 23:26 ` [PATCH v4 0/3] Second step of 'show' rewrite Austin Clements
2012-01-23 23:26   ` [PATCH v4 1/3] mime node: Record depth-first part numbers Austin Clements
2012-01-23 23:26   ` [PATCH v4 2/3] show: Use consistent header ordering in the text format Austin Clements
2012-01-23 23:26   ` [PATCH v4 3/3] show: Introduce mime_node formatter callback Austin Clements
2012-01-23 23:33 ` [PATCH v5 0/2] Second step of 'show' rewrite Austin Clements
2012-01-23 23:33   ` [PATCH v5 1/2] mime node: Record depth-first part numbers Austin Clements
2012-01-23 23:36     ` Dmitry Kurochkin
2012-01-24  8:57     ` Tomi Ollila
2012-01-23 23:33   ` [PATCH v5 2/2] show: Introduce mime_node formatter callback Austin Clements
2012-01-23 23:36     ` Dmitry Kurochkin
2012-01-24  8:58     ` Tomi Ollila
2012-01-24 18:26     ` Jani Nikula
2012-01-25 11:33   ` [PATCH v5 0/2] Second step of 'show' rewrite David Bremner

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

  List information: https://notmuchmail.org/

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

  git send-email \
    --in-reply-to=20120119021254.GJ16740@mit.edu \
    --to=amdragon@mit.edu \
    --cc=dkg@fifthhorseman.net \
    --cc=jani@nikula.org \
    --cc=notmuch@notmuchmail.org \
    /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.
Code repositories for project(s) associated with this public inbox

	https://yhetil.org/notmuch.git/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).