From 27d0db000669b13f9e61ee5c08d30563ba0d2dbf Mon Sep 17 00:00:00 2001 From: Keith Marshall Date: Wed, 9 Nov 2011 05:54:57 +0000 Subject: [PATCH] Avoid unnecessary downloads for already installed packages. --- ChangeLog | 20 ++++++++++++++++++++ src/climain.cpp | 2 +- src/pkgdeps.cpp | 15 ++++++++++----- src/pkgexec.cpp | 8 ++++++++ src/pkginet.cpp | 10 +++++++--- 5 files changed, 46 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7e8dc64..06719ec 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,23 @@ +2011-11-09 Keith Marshall + + Avoid unnecessary downloads for already installed packages. + + * src/pkginet.cpp (pkgActionItem::DownloadSingleArchive): Require + external scheduling of ACTION_DOWNLOAD; cancel the scheduled request + on completion, or when not required due to pre-existing local copy. + + * src/climain.cpp (pkgActionItem::GetSourceArchive): Must always be + prepared to download the associated archive; enable ACTION_DOWNLOAD. + + * src/pkgexec.cpp (pkgActionItem::Schedule) [OPTION_REINSTALL]: + May need to download the archive, even when the requested package was + previously installed; schedule ACTION_DOWNLOAD to enable this. + + * src/pkgdeps.cpp (promote): Macro redefined in terms of... + (with_flags, with_download): ...these new macros; implement and... + (pkgXmlDocument::ResolveDependencies): ...use them to enable/schedule + ACTION_DOWNLOAD only when expected that it may be necessary. + 2011-11-06 Keith Marshall Fix packaging anomalies for source and licence distributions. diff --git a/src/climain.cpp b/src/climain.cpp index 72cf516..20e1213 100644 --- a/src/climain.cpp +++ b/src/climain.cpp @@ -342,7 +342,7 @@ void pkgActionItem::GetSourceArchive( pkgXmlNode *package, unsigned long categor * least check that the source package is available in the * source archive cache, and if not, download it... */ - const char *path_template; + const char *path_template; flags |= ACTION_DOWNLOAD; DownloadSingleArchive( src, path_template = (category == ACTION_SOURCE) ? pkgSourceArchivePath() : pkgArchivePath() ); diff --git a/src/pkgdeps.cpp b/src/pkgdeps.cpp index d0c3745..e3f669e 100644 --- a/src/pkgdeps.cpp +++ b/src/pkgdeps.cpp @@ -196,9 +196,12 @@ bool is_abi_compatible( pkgSpecs *refdata, const char *version ) return ((version != NULL) && (strcmp( version, ref_version ) == 0)); } +#define with_flags( request ) ((request) & ~(ACTION_MASK)) +#define promote( request, action ) (with_flags( request ) | with_download( action )) +#define with_download( action ) ((action) | (ACTION_DOWNLOAD)) + void pkgXmlDocument::ResolveDependencies( pkgXmlNode* package, pkgActionItem* rank ) -# define promote( request, action ) (((request) & (~ACTION_MASK)) | action ) { /* For the specified "package", (nominally a "release"), identify its * prerequisites, (as specified by "requires" tags), and schedule actions @@ -341,13 +344,13 @@ pkgXmlDocument::ResolveDependencies( pkgXmlNode* package, pkgActionItem* rank ) /* ...this package is already installed, so we may schedule * a resolved dependency match, with no pending action... */ - unsigned long fallback = request & ~ACTION_MASK; + unsigned long fallback = with_flags( request ); if( (selected != NULL) && (selected != installed) ) { /* ...but, if there is a better candidate than the installed * version, we prefer to schedule an upgrade. */ - fallback |= ACTION_UPGRADE; + fallback |= with_download( ACTION_UPGRADE ); DEBUG_INVOKE_IF( DEBUG_REQUEST( DEBUG_TRACE_DEPENDENCIES ), dmh_printf( "%*s%s: schedule replacement\n", indent, "", installed->GetPropVal( tarname_key, value_unknown ) @@ -631,7 +634,9 @@ void pkgXmlDocument::Schedule( unsigned long action, const char* name ) * ...in which case, we must recursively resolve * any dependencies for the scheduled "upgrade". */ - ResolveDependencies( upgrade, Schedule( action, latest )); + ResolveDependencies( + upgrade, Schedule( with_download( action ), latest ) + ); else { /* attempting ACTION_UPGRADE or ACTION_REMOVE @@ -682,7 +687,7 @@ void pkgXmlDocument::Schedule( unsigned long action, const char* name ) */ unsigned long fallback = action; if( (action & ACTION_MASK) == ACTION_INSTALL ) - fallback = ACTION_UPGRADE + (action & ~ACTION_MASK); + fallback = with_download( ACTION_UPGRADE ) | with_flags( action ); /* Again, we recursively resolve any dependencies * for the scheduled upgrade. diff --git a/src/pkgexec.cpp b/src/pkgexec.cpp index 399d2e0..8ee045a 100644 --- a/src/pkgexec.cpp +++ b/src/pkgexec.cpp @@ -242,6 +242,14 @@ pkgActionItem::Schedule( unsigned long action, pkgActionItem& item ) * and return it for inclusion in the task schedule. */ pkgActionItem *rtn = new pkgActionItem(); *rtn = item; + if( pkgOptions()->Test( OPTION_REINSTALL ) == OPTION_REINSTALL ) + /* + * When the user specified the "--reinstall" option, either + * explicitly, or implied by "--download-only", (or even as a + * side effect of "--print-uris"), we MUST enable a download + * action, in case it is required to complete the request. + */ + action |= ACTION_DOWNLOAD; rtn->flags = action | (rtn->flags & ~ACTION_MASK); return rtn; } diff --git a/src/pkginet.cpp b/src/pkginet.cpp index e89f24a..29bae87 100644 --- a/src/pkginet.cpp +++ b/src/pkginet.cpp @@ -673,11 +673,11 @@ void pkgActionItem::DownloadSingleArchive /* Check if the required archive is already available locally... */ - if( (access( download.DestFile(), R_OK ) != 0) && (errno == ENOENT) ) + if( ((flags & ACTION_DOWNLOAD) == ACTION_DOWNLOAD) + && ((access( download.DestFile(), R_OK ) != 0) && (errno == ENOENT)) ) { /* ...if not, ask the download agent to fetch it... */ - flags |= ACTION_DOWNLOAD; const char *url_template = get_host_info( Selection(), uri_key ); if( url_template != NULL ) { @@ -691,7 +691,7 @@ void pkgActionItem::DownloadSingleArchive /* * Download was successful; clear the pending flag. */ - flags &= ~ACTION_DOWNLOAD; + flags &= ~(ACTION_DOWNLOAD); else /* Diagnose failure; leave pending flag set. */ @@ -707,6 +707,10 @@ void pkgActionItem::DownloadSingleArchive "Get package: %s: no URL specified for download\n", package_name ); } + else + /* There was no need to download any file to satisfy this request. + */ + flags &= ~(ACTION_DOWNLOAD); } void pkgActionItem::DownloadArchiveFiles( pkgActionItem *current ) -- 2.11.0