OSDN Git Service

Implement pre-emptive update issue number identification.
authorKeith Marshall <keithmarshall@users.sourceforge.net>
Fri, 19 Apr 2013 11:48:31 +0000 (12:48 +0100)
committerKeith Marshall <keithmarshall@users.sourceforge.net>
Fri, 19 Apr 2013 11:48:31 +0000 (12:48 +0100)
ChangeLog
src/pkgbind.cpp
src/pkginet.cpp
src/pkgkeys.h

index f6d2fca..0a19be8 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+2013-04-19  Keith Marshall  <keithmarshall@users.sourceforge.net>
+
+       Implement pre-emptive update issue number identification.
+
+       * src/pkgkeys.h (serial_number): Declare function prototype.
+       * src/pkginet.cpp (serial_number): Implementation remains here;
+       promote from static to extern "C".
+
+       * src/pkgbind.cpp (value_assumed_new): New char constant; define it.
+       (pkgRepository::expected_issue): New private member var; declare and...
+       (pkgRepository::pkgRepository): ...initialise it, assuming new.
+       (pkgRepository::GetPackageList): Assign pre-emptively declared issue
+       number, (from package-list references), to 'expected_issue'; compare it
+       with 'current_issue' number recorded within locally stored catalogue.
+       [current_issue >= expected_issue]: Suppress redundant download; adjust
+       diagnostic messages as appropriate.
+
 2013-04-10  Keith Marshall  <keithmarshall@users.sourceforge.net>
 
        Fix MinGW-Bug #1601 (on new issues tracker).
index 2f55fde..a6de809 100644 (file)
@@ -53,6 +53,7 @@ class pkgRepository
     pkgXmlNode *dbase;
     pkgXmlNode *repository;
     pkgXmlDocument *owner;
+    const char *expected_issue;
     static int count, total;
     bool force_update;
 };
@@ -63,12 +64,24 @@ class pkgRepository
 int pkgRepository::count;
 int pkgRepository::total;
 
+/* The relative age of catalogue files is determined by alpha-numeric
+ * lexical comparison of a ten digit "issue number" string; internally,
+ * we use a "pseudo issue number" represented as "XXXXXXXXXX", when we
+ * wish to pre-emptively assume that the repository may serve a newer
+ * version of any catalogue which is already present locally; (users
+ * may specify "ZZZZZZZZZZ" to override such assumptions).
+ *
+ * Here, we define the string representing assumed newness.
+ */
+static const char *value_assumed_new = "XXXXXXXXXX";
+
 pkgRepository::pkgRepository
 /*
  * Constructor...
  */
 ( pkgXmlDocument *client, pkgXmlNode *db, pkgXmlNode *ref, bool mode ):
-owner( client ), dbase( db ), repository( ref ), force_update( mode ){}
+owner( client ), dbase( db ), repository( ref ), force_update( mode ),
+expected_issue( value_assumed_new ){}
 
 void pkgRepository::GetPackageList( const char *dname )
 {
@@ -89,12 +102,27 @@ void pkgRepository::GetPackageList( const char *dname )
        */
       ++count;
 
-      /* Check for a locally cached copy of the "package-list" file...
+      /* Set up diagnostics for reporting catalogue loading progress.
        */
-      const char *mode = "Loading";
+      const char *mode = force_update ? "Retaining" : "Loading";
       const char *fmt = "%s catalogue: %s.xml; (item %d of %d)\n";
-      if( force_update || (access( dfile, F_OK ) != 0) )
+
+      /* Check for a locally cached copy of the "package-list" file...
+       */
+      const char *current_issue;
+      if(  ((current_issue = serial_number( dfile )) == NULL)
+      /*
+       * ...and, when present, make a pre-emptive assessment of any
+       * necessity to download and update to a newer version.
+       */
+      ||  (force_update && (strcmp( current_issue, expected_issue ) < 0))  )
       {
+       /* Once we've tested it, for possible availability of a more
+        * recent issue, we have no further need to refer to the issue
+        * number of the currently cached catalogue.
+        */
+       free( (void *)(current_issue) );
+
        /* When performing an "update", or if no local copy is available...
         * Force a "sync", to fetch a copy from the public host.
         */
@@ -127,12 +155,13 @@ void pkgRepository::GetPackageList( const char *dname )
         */
        owner->ProgressMeter()->Annotate( fmt, mode, dname, count, total );
 
-      else if( pkgOptions()->Test( OPTION_VERBOSE ) > 1 )
+      else if( force_update || (pkgOptions()->Test( OPTION_VERBOSE ) > 1) )
        /*
         * Similarly, this is a request to load a local copy of
         * the catalogue; progress metering is not in effect, but
-        * the user has requested verbose diagnostics, so issue
-        * a diagnostic progress report.
+        * the user has requested either an update when there was
+        * none available, or verbose diagnostics but no update,
+        * so issue a diagnostic progress report.
         */
        dmh_printf( fmt, mode, dname, count, total );
 
@@ -231,6 +260,7 @@ void pkgRepository::GetPackageList( pkgXmlNode *catalogue )
   {
     /* Evaluate each identified "package-list" catalogue in turn...
      */
+    expected_issue = catalogue->GetPropVal( issue_key, value_assumed_new );
     GetPackageList( catalogue->GetPropVal( catalogue_key, NULL ) );
 
     /* A repository may comprise an arbitrary collection of software
index 586fa39..8128114 100644 (file)
@@ -874,11 +874,11 @@ int pkgInternetLzmaStreamingAgent::TransferData( int fd )
   return dl_status;
 }
 
-static const char *serial_number( const char *catalogue )
+EXTERN_C const char *serial_number( const char *catalogue )
 {
-  /* Local helper function to retrieve issue numbers from any repository
-   * package catalogue; returns the result as a duplicate of the internal
-   * string, allocated on the heap (courtesy of the strdup() function).
+  /* Helper function to retrieve the issue serial number from any package
+   * catalogue; returns the result as a duplicate of the internal string,
+   * allocated on the heap (courtesy of the strdup() function).
    */
   const char *issue;
   pkgXmlDocument src( catalogue );
index 09738e4..12c404b 100644 (file)
@@ -89,4 +89,13 @@ EXTERN_C_DECL const char *value_unknown;
 EXTERN_C_DECL const char *value_virtual;
 EXTERN_C_DECL const char *value_yes;
 
+/* Helper function to retrieve the serial number associated with
+ * the "issue_key" attribute in any package catalogue.  This was
+ * originally implemented as a static function within pkginet.cpp
+ * Now exposed publicly, its implementation remains there; since
+ * it must be compiled as C++, it is convenient to keep it there;
+ * (e.g. it could not be conveniently relocated to pkgkeys.c).
+ */
+EXTERN_C const char *serial_number( const char * );
+
 #endif /* PKGKEYS_H: $RCSfile$: end of file */