All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Yann E. MORIN" <yann.morin.1998@free.fr>
To: Jean Delvare <jdelvare@suse.de>
Cc: linux-kbuild@vger.kernel.org, linux-kernel@vger.kernel.org,
	Michal Marek <mmarek@suse.cz>,
	Roland Eggner <edvx1@systemanalysen.net>,
	Wang YanQing <udknight@gmail.com>
Subject: Re: [PATCH 12/15] kconfig: sort found symbols by relevance
Date: Mon, 8 Jul 2013 19:35:35 +0200	[thread overview]
Message-ID: <20130708173535.GB3206@free.fr> (raw)
In-Reply-To: <1373282357.4298.198.camel@chaos.site>

Jean, All,

On 2013-07-08 13:19 +0200, Jean Delvare spake thusly:
> Le Monday 24 June 2013 à 20:11 +0200, Yann E. MORIN a écrit :
> > From: "Yann E. MORIN" <yann.morin.1998@free.fr>
[--SNIP--]
> > Since the search can be a regexp, it is possible that more than one symbol
> > matches exactly. In this case, we can't decide which to sort first, so we
> > fallback to alphabeticall sort.
> 
> Typo: alphabetical.

OK.

> > Explain this (new!) sorting heuristic in the documentation.
> 
> It's more of a rule than a heuristic.

OK.

> > Reported-by: Jean Delvare <jdelvare@suse.de>
> > Signed-off-by: "Yann E. MORIN" <yann.morin.1998@free.fr>
> > Cc: Jean Delvare <jdelvare@suse.de>
> > Cc: Michal Marek <mmarek@suse.cz>
> > Cc: Roland Eggner <edvx1@systemanalysen.net>
> > Cc: Wang YanQing <udknight@gmail.com>
> 
> I tested it and it works fine, thanks!
> 
> Tested-by: Jean Delvare <jdelvare@suse.de>
> 
> Now comes my late review. Overall I like the idea and the code but a few
> things could be improved:

Since this is already in Michal's tree, on should I proceed?
  - send an updated patch that replaces that one, or
  - send another additional patch with your proposed changes?

> > +	When searching, symbols are sorted thus:
> > +	  - exact match first: an exact match is when the search matches
> > +	    the complete symbol name;
> 
> The use of singular seems to imply there can be only one, while there
> could be several as you explained above.

OK.

> > +	  - alphabetical order: when two symbols do not match exactly,
> > +	    they are sorted in alphabetical order (in the user's current
> > +	    locale).
> 
> I think it would be better explained that way:
> 
> 	 - first, exact matches, sorted alphabetically (an exact match
> 	   is when the search matches the complete symbol name);
> 	 - then, other matches, sorted alphabetically.

OK.

> This is more concise and easier to grasp, methinks. I don't think the
> reference to the user's locale is needed, as there's no surprise here,
> and it probably doesn't matter anyway for kernel symbols.

Yes it may matter even for kernel symbols, since some locales may
consider '_' as a character to sort by, while other locales may not.

> BTW I was wondering if it would add value to explicitly print group
> header labels "Exact matches" and "Other matches" in the search results.
> What do you think?

It is not trivial to do, since the search function only returns a single
array, so there's no way for frontends (which do the display) to
differentiate which part of the array are exact matches, and which are
only partial matches.

It is much more involved, and I don't think it would be easy to
implement.

> >  ______________________________________________________________________
> >  User interface options for 'menuconfig'
> >  
> > diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c
> > index ab8f4c8..387d554 100644
> > --- a/scripts/kconfig/symbol.c
> > +++ b/scripts/kconfig/symbol.c
> > @@ -954,38 +954,98 @@ const char *sym_escape_string_value(const char *in)
> >  	return res;
> >  }
> >  
> > +struct sym_match {
> > +	struct symbol	*sym;
> > +	off_t		so, eo;
> > +};
> > +
> > +/* Compare matched symbols as thus:
> > + * - first, symbols that match exactly
> > + * - then, alphabetical sort
> > + */
> > +static int sym_rel_comp( const void *sym1, const void *sym2 )
> 
> Coding style says no space after/before parentheses.

OK.

> > +{
> > +	struct sym_match *s1 = *(struct sym_match **)sym1;
> > +	struct sym_match *s2 = *(struct sym_match **)sym2;
> 
> You shouldn't need these casts.

Probably not, indeed, but I like to write (and read) what I expect to
happen, and pointer arithmetics is always something I dread to foobar.

OK.

> > +	int l1, l2;
> > +
> > +	/* Exact match:
> > +	 * - if matched length on symbol s1 is the length of that symbol,
> > +	 *   then this symbol should come first;
> > +	 * - if matched length on symbol s2 is the length of that symbol,
> > +	 *   then this symbol should come first.
> > +	 * Note: since the search can be a regexp, both symbols may match
> > +	 * exactly; if this is the case, we can't decide which comes first,
> > +	 * and we fallback to sorting alphabetically.
> > +	 */
> > +	l1 = s1->eo - s1->so;
> > +	l2 = s2->eo - s2->so;
> > +	if (l1 == strlen(s1->sym->name) && l2 != strlen(s2->sym->name))
> > +		return -1;
> > +	if (l1 != strlen(s1->sym->name) && l2 == strlen(s2->sym->name))
> > +		return 1;
> 
> Strlen is expensive so I would avoid calling it twice on the same symbol
> name. You could store the result, together with the result of the
> comparison, while you're at it. Something like:
> 
> 	int exact1, exact2;
> 
> 	exact1 = l1 == strlen(s1->sym->name);
> 	exact2 = l2 == strlen(s2->sym->name);
> 	if (exact1 && !exact2)
> 		return -1;
> 	if (!exact1 && exact2)
> 		return 1;
> 
> You may even no longer need to introduce l1 and l2 as you would use them
> only once.

OK.

> It might be even faster to store the symbol length in struct sym_match,
> but this would increase the structure size and consequently memory
> consumption, and it is questionable if the speed gain is worth it.
> Probably not.

I intended this structure to only hold the result of the regexp match,
and nothing more. The symbol length does not belong there, IMHO.
Besides, it's easy to get back, since the symbol struct is available.

OTOH, we would gain by computing strlen at regexp match, instead of
every time in the sorting function.

But that's micro-optimisation, methinks. Searching for the example
^ATH.K took less than me focusing from the RETURN key to the screen. ;-)
 
[--SNIP--]
> >  	for_all_symbols(i, sym) {
> > +		struct sym_match *tmp_sym_match;
> >  		if (sym->flags & SYMBOL_CONST || !sym->name)
> >  			continue;
> > -		if (regexec(&re, sym->name, 0, NULL, 0))
> > +		if (regexec(&re, sym->name, 1, match, 0))
> >  			continue;
> >  		if (cnt + 1 >= size) {
> 
> I think the "+ 1" can be dropped because the new array is not
> NULL-terminated.

I'll look into that.

> > -			void *tmp = sym_arr;
> > +			void *tmp;
> >  			size += 16;
> > -			sym_arr = realloc(sym_arr, size * sizeof(struct symbol *));
> > -			if (!sym_arr) {
> > -				free(tmp);
> > -				return NULL;
> > +			tmp = realloc(sym_match_arr, size * sizeof(struct sym_match *));
> > +			if (!tmp) {
> > +				goto sym_re_search_free;
> >  			}
> 
> Unnecessary curly braces (as reported by checkpatch.) Checkpatch reports
> a few other issues BTW, you should run it and fix them.

My fault, as I always use curly braces, even around single statements,
in many other projects. ( /me believes this kernel coding style is bad,
but will abide by the rules! ;-) ).

OK.

> > +			sym_match_arr = tmp;
> >  		}
> >  		sym_calc_value(sym);
> > -		sym_arr[cnt++] = sym;
> > +		tmp_sym_match = (struct sym_match*)malloc(sizeof(struct sym_match));
> 
> Cast not needed.

OK.

> In fact I don't think this allocation is needed in the first place.
> Calling malloc for every match is rather costly. If you would have
> allocated an array of struct sym_match (rather than only pointers
> thereto) before, you would not need this per-symbol malloc. Struct
> sym_match is small enough to not warrant an extra level of allocation
> and indirection IMHO.

OK, will look into that.

Thank you for the review! :-)

Regards,
Yann E. MORIN.

-- 
.-----------------.--------------------.------------------.--------------------.
|  Yann E. MORIN  | Real-Time Embedded | /"\ ASCII RIBBON | Erics' conspiracy: |
| +33 662 376 056 | Software  Designer | \ / CAMPAIGN     |  ___               |
| +33 223 225 172 `------------.-------:  X  AGAINST      |  \e/  There is no  |
| http://ymorin.is-a-geek.org/ | _/*\_ | / \ HTML MAIL    |   v   conspiracy.  |
'------------------------------^-------^------------------^--------------------'

  reply	other threads:[~2013-07-08 17:35 UTC|newest]

Thread overview: 36+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-06-24 18:11 [pull request v2] Pull request for branch yem-kconfig-for-next Yann E. MORIN
2013-06-24 18:11 ` [PATCH 01/15] kconfig: Fix defconfig when one choice menu selects options that another choice menu depends on Yann E. MORIN
2013-06-24 18:11 ` [PATCH 02/15] kconfig/lxdialog: Add definitions for mininimum (re)size values Yann E. MORIN
2013-06-24 18:11 ` [PATCH 03/15] kconfig/lxdialog: Use new mininimum resize definitions in conf_choice() Yann E. MORIN
2013-06-24 18:11 ` [PATCH 04/15] kconfig/lxdialog: handle newline characters in print_autowrap() Yann E. MORIN
2013-06-24 18:11 ` [PATCH 05/15] mconf: use function calls instead of ncurses' variables LINES and COLS Yann E. MORIN
2013-06-24 18:11 ` [PATCH 06/15] nconf: " Yann E. MORIN
2013-06-24 18:11 ` [PATCH 07/15] mconf/nconf: mark empty menus/menuconfigs different from non-empty ones Yann E. MORIN
2013-06-24 18:11 ` [PATCH 08/15] scripts/config: replace hard-coded script name by a dynamic value Yann E. MORIN
2013-06-24 18:11 ` [PATCH 09/15] kconfig/conf: fix randconfig setting multiple symbols in a choice Yann E. MORIN
2013-06-25  7:23   ` Sedat Dilek
2013-06-24 18:11 ` [PATCH 10/15] kconfig/conf: accept a base-16 seed for randconfig Yann E. MORIN
2013-06-24 18:11 ` [PATCH 11/15] kconfig/conf: print the seed used to initialise the RNG " Yann E. MORIN
2013-06-24 18:11 ` [PATCH 12/15] kconfig: sort found symbols by relevance Yann E. MORIN
2013-07-08 11:19   ` Jean Delvare
2013-07-08 17:35     ` Yann E. MORIN [this message]
2013-07-10 20:46       ` Yann E. MORIN
2013-07-12  9:07         ` Jean Delvare
2013-07-13 13:06           ` Yann E. MORIN
2013-07-12  8:57       ` Jean Delvare
2013-06-24 18:11 ` [PATCH 13/15] kconfig/[mn]conf: make it explicit in the search box that a regexp is possible Yann E. MORIN
2013-07-08 11:25   ` Jean Delvare
2013-07-08 17:37     ` Yann E. MORIN
2013-07-16 14:31       ` Jean Delvare
2013-07-16 14:39         ` Yann E. MORIN
2013-06-24 18:11 ` [PATCH 14/15] kconfig: loop as long as we changed some symbols in randconfig Yann E. MORIN
2013-06-24 18:11 ` [PATCH 15/15] kconfig: fix randomising choice entries in presence of KCONFIG_ALLCONFIG Yann E. MORIN
2013-06-25  8:01   ` Yann E. MORIN
2013-06-25  8:10     ` Sedat Dilek
2013-06-25 20:58   ` Yann E. MORIN
2013-06-25 21:37     ` [PATCH] Revert "kconfig: fix randomising choice entries in presence of KCONFIG_ALLCONFIG" Yann E. MORIN
2013-06-26 13:48       ` Michal Marek
2013-06-26 21:44         ` Yann E. MORIN
2013-06-27  6:23           ` Sedat Dilek
2013-06-28 17:19             ` Yann E. MORIN
2013-06-24 21:42 ` [pull request v2] Pull request for branch yem-kconfig-for-next Michal Marek

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=20130708173535.GB3206@free.fr \
    --to=yann.morin.1998@free.fr \
    --cc=edvx1@systemanalysen.net \
    --cc=jdelvare@suse.de \
    --cc=linux-kbuild@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mmarek@suse.cz \
    --cc=udknight@gmail.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.