unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
From: Artur Malabarba <bruce.connor.am@gmail.com>
To: Davis Herring <herring@lanl.gov>
Cc: Stefan Monnier <monnier@iro.umontreal.ca>,
	emacs-devel <emacs-devel@gnu.org>
Subject: Re: [Emacs-diffs] scratch/package-fix e5d5cdf 1/2: emacs-lisp/package.el: Indicate incompatible packages.
Date: Fri, 13 Feb 2015 13:48:21 +0000	[thread overview]
Message-ID: <CAAdUY-KLzqpPO5oGMKALCTvsb09_PBTTcEae=NKa2UwVp0kWuA@mail.gmail.com> (raw)
In-Reply-To: <54DCD63C.5090000@lanl.gov>

2015-02-12 16:35 GMT+00:00 Davis Herring <herring@lanl.gov>:
>> The algorithmic problem is quite real, indeed.
>> We could solve it by adding a "compatible" field to the struct, which
>> we'd set to `yes' or `no' (so as to memoize previous computations), so
>> the complexity would stay linear in the number of packages (though also
>> linear in the number of number of `requires').
>
> The compatible flag need not be added to the struct; it could instead be
> maintained in a hash table retained only for the duration of printing.
> (Then it has to be recomputed once per listing, but as it's linear that
> probably doesn't matter.)

I've just pushed an initial implementation of this. There is a hash
table which lists the highest compatible version for each package
(regardless of whether the package is installed or available). This
compatibility is in the shallowest sense (the package's “emacs”
dependency isn't higher than emacs-version).
This table is populated in package-read-all-descriptors.

Then, the package--incompatible-p function does the Emacs version
checking and also checks the dependencies using the hashtable. This
dependency checking is not recursive yet.

The first step for making the dependency checking recursive (without
making it quadratic) would be to store actual package-desc objects in
the hash-table so their dependencies are immediately available
(without having to find the object in the relevant alist).
However, there is one obstacle that makes this non-trivial:

- Package A-1.0 depends on B-1.0 which depends on C-1.0.
- There's a new available version B-2.0 which depends on an
incompatible version of C-2.0.
- B-1.0 and C-1.0 are installed (and compatible).
- Therefore, package A-1.0 can be installed (is compatible).

In the current implementation, everything works:

- The hashtable will store: [(A 1.0) (B 2.0) (C 1.0)] (remember, the
hashtable only stores a shallow check).
- The function package--incompatible-p (this is what does the full
check) will correctly indicate B-2.0 and C-2.0 are NOT compatible, and
correctly indicate A-1.0, B-1.0, and C-1.0 are all compatible. It
works because A-1.0's only dependency is met in the hashtable (by
B-2.0).

On the other hand, if we naively make package--incompatible-p check
deps recursively, then A-1.0's check will fail because B-2.0 fails.

The perfect answer to this would be for the hashtable to only store
fully compatible packages (so it would store B-1.0 instead of B-2.0),
but I can't figure out a way to do that while keeping the hashtable
build algorithm linear in the number of packages. The hashtable
rebuilds every time the package list is refreshed, so I'd rather not
make it quadratic, but maybe that's not a huge deal.



  reply	other threads:[~2015-02-13 13:48 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20150211170820.10979.16862@vcs.savannah.gnu.org>
     [not found] ` <E1YLalx-0002s8-E8@vcs.savannah.gnu.org>
2015-02-11 19:28   ` [Emacs-diffs] scratch/package-fix e5d5cdf 1/2: emacs-lisp/package.el: Indicate incompatible packages Stefan Monnier
2015-02-11 23:00     ` Artur Malabarba
2015-02-12 14:41       ` Stefan Monnier
2015-02-12 16:35         ` Davis Herring
2015-02-13 13:48           ` Artur Malabarba [this message]
2015-02-12 21:42         ` chad
2015-02-13 20:13           ` Stefan Monnier
2015-02-13 20:18             ` Artur Malabarba
2015-02-14 18:04               ` Artur Malabarba

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://www.gnu.org/software/emacs/

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

  git send-email \
    --in-reply-to='CAAdUY-KLzqpPO5oGMKALCTvsb09_PBTTcEae=NKa2UwVp0kWuA@mail.gmail.com' \
    --to=bruce.connor.am@gmail.com \
    --cc=emacs-devel@gnu.org \
    --cc=herring@lanl.gov \
    --cc=monnier@iro.umontreal.ca \
    /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://git.savannah.gnu.org/cgit/emacs.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).