aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2010-06-26 19:45:58 +0100
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2010-06-26 19:45:58 +0100
commit1194540f09b1e4e8f620aac4a79180dd19aa7f4c (patch)
tree04e5fca856122ca5d68ecad4a244dfcfa6b3a794
parent1842b15a88f5f0a956851e89ba1fd2b98f4787ef (diff)
downloadpaludis-1194540f09b1e4e8f620aac4a79180dd19aa7f4c.tar.gz
paludis-1194540f09b1e4e8f620aac4a79180dd19aa7f4c.tar.xz
Fetch deps
-rw-r--r--paludis/resolver/Makefile.am13
-rw-r--r--paludis/resolver/nag-fwd.hh3
-rw-r--r--paludis/resolver/nag.cc16
-rw-r--r--paludis/resolver/nag.hh2
-rw-r--r--paludis/resolver/nag.se14
-rw-r--r--paludis/resolver/orderer.cc183
6 files changed, 169 insertions, 62 deletions
diff --git a/paludis/resolver/Makefile.am b/paludis/resolver/Makefile.am
index 660c5aa..648b603 100644
--- a/paludis/resolver/Makefile.am
+++ b/paludis/resolver/Makefile.am
@@ -3,9 +3,10 @@ include $(top_srcdir)/misc/common-makefile.am
DISTCLEANFILES = \
any_child_score-se.hh any_child_score-se.cc \
change_type-se.hh change_type-se.cc \
- job_requirements-se.hh job_requirements-se.cc \
destination_types-se.hh destination_types-se.cc \
- resolver_functions-se.hh resolver_functions-se.cc \
+ job_requirements-se.hh job_requirements-se.cc \
+ nag-se.hh nag-se.cc \
+ resolver_functions-se.hh resolver_functions-se.cc \ \
use_existing-se.hh use_existing-se.cc
AM_CXXFLAGS = -I$(top_srcdir) @PALUDIS_CXXFLAGS@ @PALUDIS_CXXFLAGS_VISIBILITY@
EXTRA_DIST = \
@@ -13,6 +14,7 @@ EXTRA_DIST = \
change_type-se.hh change_type-se.cc change_type.se \
destination_types-se.hh destination_types-se.cc destination_types.se \
job_requirements-se.hh job_requirements-se.cc job_requirements.se \
+ nag-se.hh nag-se.cc nag.se \
resolver_functions-se.hh resolver_functions-se.cc resolver_functions.se \
use_existing-se.hh use_existing-se.cc use_existing.se \
$(check_SCRIPTS)
@@ -20,6 +22,7 @@ BUILT_SOURCES = \
any_child_score-se.hh any_child_score-se.cc \
change_type-se.hh change_type-se.cc \
destination_types-se.hh destination_types-se.cc \
+ nag-se.hh nag-se.cc \
job_requirements-se.hh job_requirements-se.cc \
resolver_functions-se.hh resolver_functions-se.cc \
use_existing-se.hh use_existing-se.cc
@@ -298,3 +301,9 @@ job_requirements-se.hh : job_requirements.se $(top_srcdir)/misc/make_se.bash
job_requirements-se.cc : job_requirements.se $(top_srcdir)/misc/make_se.bash
if ! $(top_srcdir)/misc/make_se.bash --source $(srcdir)/job_requirements.se > $@ ; then rm -f $@ ; exit 1 ; fi
+nag-se.hh : nag.se $(top_srcdir)/misc/make_se.bash
+ if ! $(top_srcdir)/misc/make_se.bash --header $(srcdir)/nag.se > $@ ; then rm -f $@ ; exit 1 ; fi
+
+nag-se.cc : nag.se $(top_srcdir)/misc/make_se.bash
+ if ! $(top_srcdir)/misc/make_se.bash --source $(srcdir)/nag.se > $@ ; then rm -f $@ ; exit 1 ; fi
+
diff --git a/paludis/resolver/nag-fwd.hh b/paludis/resolver/nag-fwd.hh
index b41ccc8..615fa49 100644
--- a/paludis/resolver/nag-fwd.hh
+++ b/paludis/resolver/nag-fwd.hh
@@ -27,6 +27,9 @@ namespace paludis
{
namespace resolver
{
+
+#include <paludis/resolver/nag-se.hh>
+
struct NAG;
struct NAGIndex;
struct NAGEdgeProperties;
diff --git a/paludis/resolver/nag.cc b/paludis/resolver/nag.cc
index e131527..352dbea 100644
--- a/paludis/resolver/nag.cc
+++ b/paludis/resolver/nag.cc
@@ -41,6 +41,8 @@
using namespace paludis;
using namespace paludis::resolver;
+#include <paludis/resolver/nag-se.cc>
+
typedef std::tr1::unordered_set<NAGIndex, Hash<NAGIndex> > Nodes;
typedef std::tr1::unordered_map<NAGIndex, NAGEdgeProperties, Hash<NAGIndex> > NodesWithProperties;
typedef std::tr1::unordered_map<NAGIndex, NodesWithProperties, Hash<NAGIndex> > Edges;
@@ -55,19 +57,23 @@ NAGIndex::hash() const
bool
paludis::resolver::operator< (const NAGIndex & a, const NAGIndex & b)
{
- return a.resolvent() < b.resolvent();
+ if (a.resolvent() < b.resolvent())
+ return true;
+ if (b.resolvent() < a.resolvent())
+ return false;
+ return a.role() < b.role();
}
bool
paludis::resolver::operator== (const NAGIndex & a, const NAGIndex & b)
{
- return a.resolvent() == b.resolvent();
+ return a.resolvent() == b.resolvent() && a.role() == b.role();
}
std::ostream &
paludis::resolver::operator<< (std::ostream & s, const NAGIndex & r)
{
- s << r.resolvent();
+ s << r.role() << " " << r.resolvent();
return s;
}
@@ -76,6 +82,7 @@ NAGIndex::serialise(Serialiser & s) const
{
s.object("NAGIndex")
.member(SerialiserFlags<>(), "resolvent", resolvent())
+ .member(SerialiserFlags<>(), "role", stringify(role()))
;
}
@@ -85,7 +92,8 @@ NAGIndex::deserialise(Deserialisation & d)
Deserialisator v(d, "NAGIndex");
return make_named_values<NAGIndex>(
- n::resolvent() = v.member<Resolvent>("resolvent")
+ n::resolvent() = v.member<Resolvent>("resolvent"),
+ n::role() = destringify<NAGIndexRole>(v.member<std::string>("role"))
);
}
diff --git a/paludis/resolver/nag.hh b/paludis/resolver/nag.hh
index 68d96d7..900f747 100644
--- a/paludis/resolver/nag.hh
+++ b/paludis/resolver/nag.hh
@@ -36,6 +36,7 @@ namespace paludis
typedef Name<struct build_name> build;
typedef Name<struct build_all_met_name> build_all_met;
typedef Name<struct resolvent_name> resolvent;
+ typedef Name<struct role_name> role;
typedef Name<struct run_name> run;
typedef Name<struct run_all_met_name> run_all_met;
}
@@ -45,6 +46,7 @@ namespace paludis
struct NAGIndex
{
NamedValue<n::resolvent, Resolvent> resolvent;
+ NamedValue<n::role, NAGIndexRole> role;
std::size_t hash() const PALUDIS_ATTRIBUTE((warn_unused_result));
diff --git a/paludis/resolver/nag.se b/paludis/resolver/nag.se
new file mode 100644
index 0000000..d66c863
--- /dev/null
+++ b/paludis/resolver/nag.se
@@ -0,0 +1,14 @@
+#!/usr/bin/env bash
+# vim: set sw=4 sts=4 et ft=sh :
+
+make_enum_NAGIndexRole()
+{
+ prefix nir
+ namespace paludis::resolver
+
+ key nir_fetched "Fetched"
+ key nir_done "Done"
+
+ want_destringify
+}
+
diff --git a/paludis/resolver/orderer.cc b/paludis/resolver/orderer.cc
index 2c6fbe3..879d8b2 100644
--- a/paludis/resolver/orderer.cc
+++ b/paludis/resolver/orderer.cc
@@ -52,6 +52,7 @@ using namespace paludis::resolver;
typedef std::tr1::unordered_map<NAGIndex, std::tr1::shared_ptr<const ChangeOrRemoveDecision>, Hash<NAGIndex> > ChangeOrRemoveIndices;
typedef std::tr1::unordered_map<NAGIndex, JobNumber, Hash<NAGIndex> > InstallJobNumbers;
+typedef std::tr1::unordered_map<Resolvent, JobNumber, Hash<Resolvent> > FetchJobNumbers;
namespace paludis
{
@@ -61,6 +62,7 @@ namespace paludis
const Environment * const env;
const std::tr1::shared_ptr<Resolved> resolved;
ChangeOrRemoveIndices change_or_remove_indices;
+ FetchJobNumbers fetch_job_numbers;
InstallJobNumbers install_job_numbers;
Implementation(
@@ -127,7 +129,8 @@ namespace
bool visit(const NothingNoChangeDecision &)
{
resolved->nag()->add_node(make_named_values<NAGIndex>(
- n::resolvent() = resolvent
+ n::resolvent() = resolvent,
+ n::role() = nir_done
));
return true;
}
@@ -135,7 +138,8 @@ namespace
bool visit(const ExistingNoChangeDecision &)
{
resolved->nag()->add_node(make_named_values<NAGIndex>(
- n::resolvent() = resolvent
+ n::resolvent() = resolvent,
+ n::role() = nir_done
));
return true;
}
@@ -144,12 +148,30 @@ namespace
{
if (decision->taken())
{
- NAGIndex index(make_named_values<NAGIndex>(
- n::resolvent() = resolvent
+ NAGIndex fetched_index(make_named_values<NAGIndex>(
+ n::resolvent() = resolvent,
+ n::role() = nir_fetched
));
- resolved->nag()->add_node(index);
- change_or_remove_indices.insert(std::make_pair(index,
+ resolved->nag()->add_node(fetched_index);
+ change_or_remove_indices.insert(std::make_pair(fetched_index,
+ std::tr1::static_pointer_cast<const ChangeOrRemoveDecision>(decision)));
+
+ NAGIndex done_index(make_named_values<NAGIndex>(
+ n::resolvent() = resolvent,
+ n::role() = nir_done
+ ));
+ resolved->nag()->add_node(done_index);
+ change_or_remove_indices.insert(std::make_pair(done_index,
std::tr1::static_pointer_cast<const ChangeOrRemoveDecision>(decision)));
+
+ resolved->nag()->add_edge(done_index, fetched_index,
+ make_named_values<NAGEdgeProperties>(
+ n::build() = true,
+ n::build_all_met() = false,
+ n::run() = false,
+ n::run_all_met() = true
+ ));
+
return true;
}
else
@@ -165,7 +187,8 @@ namespace
if (decision->taken())
{
NAGIndex index(make_named_values<NAGIndex>(
- n::resolvent() = resolvent
+ n::resolvent() = resolvent,
+ n::role() = nir_done
));
resolved->nag()->add_node(index);
change_or_remove_indices.insert(std::make_pair(index,
@@ -194,11 +217,13 @@ namespace
bool build;
bool run;
bool post;
+ bool fetch;
LabelsClassifier() :
build(false),
run(false),
- post(false)
+ post(false),
+ fetch(false)
{
}
@@ -214,7 +239,7 @@ namespace
void visit(const DependenciesFetchLabel &)
{
- build = true;
+ fetch = true;
}
void visit(const DependenciesRunLabel &)
@@ -278,7 +303,7 @@ namespace
l != l_end ; ++l)
(*l)->accept(classifier);
- if (classifier.build || classifier.run)
+ if (classifier.build || classifier.run || classifier.fetch)
{
bool arrow(true);
if (r.sanitised_dependency().spec().if_block())
@@ -286,19 +311,25 @@ namespace
arrow = false;
if (arrow)
- nag->add_edge(
- make_named_values<NAGIndex>(
- n::resolvent() = r.from_resolvent()
- ),
- make_named_values<NAGIndex>(
- n::resolvent() = resolvent
- ),
+ {
+ NAGIndex from(make_named_values<NAGIndex>(
+ n::resolvent() = r.from_resolvent(),
+ n::role() = classifier.fetch ? nir_fetched : nir_done
+ ));
+
+ NAGIndex to(make_named_values<NAGIndex>(
+ n::resolvent() = resolvent,
+ n::role() = nir_done
+ ));
+
+ nag->add_edge(from, to,
make_named_values<NAGEdgeProperties>(
- n::build() = classifier.build,
- n::build_all_met() = r.already_met() || ! classifier.build,
+ n::build() = classifier.build || classifier.fetch,
+ n::build_all_met() = r.already_met() || ! (classifier.build || classifier.fetch),
n::run() = classifier.run,
n::run_all_met() = r.already_met() || ! classifier.run
));
+ }
}
else if (classifier.post)
{
@@ -630,14 +661,17 @@ namespace
struct ExtraScheduler
{
const std::tr1::shared_ptr<const Resolved> resolved;
+ FetchJobNumbers & fetch_job_numbers;
InstallJobNumbers & install_job_numbers;
const NAGIndex index;
ExtraScheduler(
const std::tr1::shared_ptr<const Resolved> & r,
+ FetchJobNumbers & f,
InstallJobNumbers & i,
const NAGIndex & v) :
resolved(r),
+ fetch_job_numbers(f),
install_job_numbers(i),
index(v)
{
@@ -645,44 +679,65 @@ namespace
void visit(const ChangesToMakeDecision & changes_to_make_decision) const
{
- resolved->job_lists()->pretend_job_list()->append(make_shared_ptr(new PretendJob(
- changes_to_make_decision.origin_id()->uniquely_identifying_spec())));
-
- JobNumber fetch_job_n(resolved->job_lists()->execute_job_list()->append(make_shared_ptr(new FetchJob(
- make_shared_ptr(new JobRequirements),
- changes_to_make_decision.origin_id()->uniquely_identifying_spec()))));
+ switch (index.role())
+ {
+ case nir_done:
+ {
+ FetchJobNumbers::const_iterator fetch_job_n(fetch_job_numbers.find(index.resolvent()));
+ if (fetch_job_n == fetch_job_numbers.end())
+ throw InternalError(PALUDIS_HERE, "haven't scheduled the fetch for " + stringify(index.resolvent()) + " yet");
- const std::tr1::shared_ptr<JobRequirements> requirements(new JobRequirements);
- requirements->push_back(make_named_values<JobRequirement>(
- n::job_number() = fetch_job_n,
- n::required_if() = JobRequirementIfs() + jri_require_for_satisfied + jri_require_for_independent + jri_require_always
- ));
+ resolved->job_lists()->pretend_job_list()->append(make_shared_ptr(new PretendJob(
+ changes_to_make_decision.origin_id()->uniquely_identifying_spec())));
- RecursedRequirements recursed;
- populate_requirements(
- resolved->nag(),
- install_job_numbers,
- index,
- requirements,
- false,
- recursed
- );
-
- const std::tr1::shared_ptr<Sequence<PackageDepSpec> > replacing(new Sequence<PackageDepSpec>);
- for (PackageIDSequence::ConstIterator i(changes_to_make_decision.destination()->replacing()->begin()),
- i_end(changes_to_make_decision.destination()->replacing()->end()) ;
- i != i_end ; ++i)
- replacing->push_back((*i)->uniquely_identifying_spec());
+ const std::tr1::shared_ptr<JobRequirements> requirements(new JobRequirements);
+ requirements->push_back(make_named_values<JobRequirement>(
+ n::job_number() = fetch_job_n->second,
+ n::required_if() = JobRequirementIfs() + jri_require_for_satisfied + jri_require_for_independent + jri_require_always
+ ));
- JobNumber install_job_n(resolved->job_lists()->execute_job_list()->append(make_shared_ptr(new InstallJob(
+ RecursedRequirements recursed;
+ populate_requirements(
+ resolved->nag(),
+ install_job_numbers,
+ index,
requirements,
- changes_to_make_decision.origin_id()->uniquely_identifying_spec(),
- changes_to_make_decision.destination()->repository(),
- changes_to_make_decision.resolvent().destination_type(),
- replacing
- ))));
+ false,
+ recursed
+ );
+
+ const std::tr1::shared_ptr<Sequence<PackageDepSpec> > replacing(new Sequence<PackageDepSpec>);
+ for (PackageIDSequence::ConstIterator i(changes_to_make_decision.destination()->replacing()->begin()),
+ i_end(changes_to_make_decision.destination()->replacing()->end()) ;
+ i != i_end ; ++i)
+ replacing->push_back((*i)->uniquely_identifying_spec());
+
+ JobNumber install_job_n(resolved->job_lists()->execute_job_list()->append(make_shared_ptr(new InstallJob(
+ requirements,
+ changes_to_make_decision.origin_id()->uniquely_identifying_spec(),
+ changes_to_make_decision.destination()->repository(),
+ changes_to_make_decision.resolvent().destination_type(),
+ replacing
+ ))));
+
+ install_job_numbers.insert(std::make_pair(index, install_job_n));
+ }
+ return;
+
+ case nir_fetched:
+ {
+ JobNumber fetch_job_n(resolved->job_lists()->execute_job_list()->append(make_shared_ptr(new FetchJob(
+ make_shared_ptr(new JobRequirements),
+ changes_to_make_decision.origin_id()->uniquely_identifying_spec()))));
+ fetch_job_numbers.insert(std::make_pair(index.resolvent(), fetch_job_n));
+ }
+ return;
+
+ case last_nir:
+ break;
+ }
- install_job_numbers.insert(std::make_pair(index, install_job_n));
+ throw InternalError(PALUDIS_HERE, "bad index.role");
}
void visit(const RemoveDecision & remove_decision) const
@@ -707,10 +762,26 @@ Orderer::_schedule(
const std::tr1::shared_ptr<const ChangeOrRemoveDecision> & d,
const std::tr1::shared_ptr<const OrdererNotes> & n)
{
- _imp->resolved->taken_change_or_remove_decisions()->push_back(d, n);
- if (d->required_confirmations_if_any())
- _imp->resolved->taken_unconfirmed_decisions()->push_back(d);
+ do
+ {
+ switch (index.role())
+ {
+ case nir_done:
+ _imp->resolved->taken_change_or_remove_decisions()->push_back(d, n);
+ if (d->required_confirmations_if_any())
+ _imp->resolved->taken_unconfirmed_decisions()->push_back(d);
+ continue;
+
+ case nir_fetched:
+ continue;
+
+ case last_nir:
+ break;
+ }
+
+ throw InternalError(PALUDIS_HERE, "bad index.role");
+ } while (false);
- d->accept(ExtraScheduler(_imp->resolved, _imp->install_job_numbers, index));
+ d->accept(ExtraScheduler(_imp->resolved, _imp->fetch_job_numbers, _imp->install_job_numbers, index));
}