Просмотр исходного кода

Generic progress meter
Author: jgg
Date: 1998-07-21 05:33:18 GMT
Generic progress meter

Arch Librarian лет назад: 22
Родитель
Сommit
404ec98e51
6 измененных файлов с 257 добавлено и 13 удалено
  1. 151 0
      apt-pkg/contrib/progress.cc
  2. 84 0
      apt-pkg/contrib/progress.h
  3. 3 3
      apt-pkg/makefile
  4. 6 2
      apt-pkg/pkgcachegen.cc
  5. 5 3
      apt-pkg/pkgcachegen.h
  6. 8 5
      cmdline/apt-cache.cc

+ 151 - 0
apt-pkg/contrib/progress.cc

@@ -0,0 +1,151 @@
+// -*- mode: cpp; mode: fold -*-
+// Description								/*{{{*/
+// $Id: progress.cc,v 1.1 1998/07/21 05:33:21 jgg Exp $
+/* ######################################################################
+   
+   OpProgress - Operation Progress
+   
+   ##################################################################### */
+									/*}}}*/
+// Include Files							/*{{{*/
+#ifdef __GNUG__
+#pragma implementation "apt-pkg/progress.h"
+#endif 
+#include <apt-pkg/progress.h>
+#include <stdio.h>
+									/*}}}*/
+
+// OpProgress::OpProgress - Constructor					/*{{{*/
+// ---------------------------------------------------------------------
+/* */
+OpProgress::OpProgress() : Current(0), Total(0), Size(0), SubTotal(1), 
+                           LastPercent(0), Percent(0)
+{
+   memset(&LastTime,0,sizeof(LastTime));
+}
+									/*}}}*/
+// OpProgress::Progress - Sub progress with no state change		/*{{{*/
+// ---------------------------------------------------------------------
+/* This assumes that Size is the same as the current sub size */
+void OpProgress::Progress(unsigned long Cur)
+{
+   Percent = (Current + Cur/((float)SubTotal)*Size)*100.0/Total;
+   Update();
+}
+									/*}}}*/
+// OpProgress::OverallProgress - Set the overall progress		/*{{{*/
+// ---------------------------------------------------------------------
+/* */
+void OpProgress::OverallProgress(unsigned long Current, unsigned long Total,
+	  			 unsigned long Size,string Op)
+{
+   this->Current = Current;
+   this->Total = Total;
+   this->Size = Size;
+   this->Op = Op;
+   SubOp = string();
+   Percent = Current*100.0/Total;
+   Update();
+}
+									/*}}}*/
+// OpProgress::SubProgress - Set the sub progress state			/*{{{*/
+// ---------------------------------------------------------------------
+/* */
+void OpProgress::SubProgress(unsigned long SubTotal,string Op)
+{
+   this->SubTotal = SubTotal;
+   SubOp = Op;
+   Percent = Current*100.0/Total;
+   Update();
+}
+									/*}}}*/
+// OpProgress::CheckChange - See if the display should be updated	/*{{{*/
+// ---------------------------------------------------------------------
+/* Progress calls are made so frequently that if every one resulted in 
+   an update the display would be swamped and the system much slower.
+   This provides an upper bound on the update rate. */
+bool OpProgress::CheckChange(float Interval)
+{  
+   // New major progress indication
+   if (Op != LastOp)
+   {
+      MajorChange = true;
+      LastOp = Op;
+      return true;
+   }
+   MajorChange = false;
+
+   if ((int)LastPercent == (int)Percent)
+      return false;
+   LastPercent = Percent;
+   
+   // Check time delta
+   struct timeval Now;
+   gettimeofday(&Now,0);
+   double Diff = Now.tv_sec - LastTime.tv_sec + (Now.tv_usec - LastTime.tv_usec)/1000000.0;
+   if (Diff < Interval)
+      return false;
+   LastTime = Now;   
+   return true;
+}
+									/*}}}*/
+// OpTextProgress::Done - Clean up the display				/*{{{*/
+// ---------------------------------------------------------------------
+/* */
+void OpTextProgress::Done()
+{
+   if (NoUpdate == false && OldOp.empty() == false)
+   {
+      char S[300];
+      snprintf(S,sizeof(S),"\r%s",OldOp.c_str());
+      Write(S);
+      cout << endl;
+      OldOp = string();
+   }      
+}
+									/*}}}*/
+// OpTextProgress::Update - Simple text spinner				/*{{{*/
+// ---------------------------------------------------------------------
+/* */
+void OpTextProgress::Update()
+{
+   if (CheckChange(0) == false)
+      return;
+   
+   // No percent spinner
+   if (NoUpdate == true)
+   {
+      if (MajorChange == false)
+	 return;
+      cout << Op << endl;
+      return;
+   }
+
+   // Erase the old text and 'log' the event
+   char S[300];
+   if (MajorChange == true && OldOp.empty() == false)
+   {
+      snprintf(S,sizeof(S),"\r%s",OldOp.c_str());
+      Write(S);
+      cout << endl;
+   }
+   
+   // Print the spinner
+   snprintf(S,sizeof(S),"\r%s... %u%%",Op.c_str(),(unsigned int)Percent);
+   Write(S);
+
+   OldOp = Op;
+}
+									/*}}}*/
+// OpTextProgress::Write - Write the progress string			/*{{{*/
+// ---------------------------------------------------------------------
+/* This space fills the end to overwrite the previous text */
+void OpTextProgress::Write(const char *S)
+{
+   cout << S;
+   for (unsigned int I = strlen(S); I < LastLen; I++)
+      cout << ' ';
+   cout << '\r' << flush;
+   LastLen = strlen(S);
+}
+									/*}}}*/

+ 84 - 0
apt-pkg/contrib/progress.h

@@ -0,0 +1,84 @@
+// -*- mode: cpp; mode: fold -*-
+// Description								/*{{{*/
+// $Id: progress.h,v 1.1 1998/07/21 05:33:21 jgg Exp $
+/* ######################################################################
+   
+   OpProgress - Operation Progress
+   
+   This class allows lengthy operations to communicate their progress 
+   to the GUI. The progress model is simple and is not designed to handle
+   the complex case of the multi-activity aquire class.
+   
+   The model is based on the concept of an overall operation consisting
+   of a series of small sub operations. Each sub operation has it's own
+   completion status and the overall operation has it's completion status.
+   The units of the two are not mixed and are completely independent.
+   
+   The UI is expected to subclass this to provide the visuals to the user.
+   
+   ##################################################################### */
+									/*}}}*/
+// Header section: pkglib
+#ifndef PKGLIB_PROGRESS_H
+#define PKGLIB_PROGRESS_H
+
+#ifdef __GNUG__
+#pragma interface "apt-pkg/progress.h"
+#endif 
+
+#include <string>
+#include <sys/time.h>
+
+class OpProgress
+{
+   unsigned long Current;
+   unsigned long Total;
+   unsigned long Size;
+   unsigned long SubTotal;
+   float LastPercent;
+   
+   // Change reduction code
+   struct timeval LastTime;
+   string LastOp;
+   
+   protected:
+   
+   string Op;
+   string SubOp;
+   float Percent;
+   
+   bool MajorChange;
+   
+   bool CheckChange(float Interval = 0.7);		    
+   virtual void Update() {};
+   
+   public:
+   
+   void Progress(unsigned long Current);
+   void SubProgress(unsigned long SubTotal,string Op);
+   void OverallProgress(unsigned long Current,unsigned long Total,
+			unsigned long Size,string Op);
+
+   OpProgress();
+   virtual ~OpProgress() {};
+};
+
+class OpTextProgress : public OpProgress
+{
+   protected:
+   
+   string OldOp;
+   bool NoUpdate;
+   unsigned long LastLen;
+   virtual void Update();
+   void Write(const char *S);
+   
+   public:
+
+   void Done();
+   
+   OpTextProgress(bool NoUpdate = false) : NoUpdate(NoUpdate), LastLen(0) {};
+   virtual ~OpTextProgress() {Done();};
+};
+
+#endif

+ 3 - 3
apt-pkg/makefile

@@ -15,8 +15,8 @@ MINOR=0.0
 
 
 # Source code for the contributed non-core things
 # Source code for the contributed non-core things
 SOURCE = contrib/mmap.cc contrib/error.cc contrib/strutl.cc \
 SOURCE = contrib/mmap.cc contrib/error.cc contrib/strutl.cc \
-         contrib/configuration.cc
-	 
+         contrib/configuration.cc contrib/progress.cc
+
 # Source code for the main library
 # Source code for the main library
 SOURCE+= pkgcache.cc version.cc fileutl.cc pkgcachegen.cc depcache.cc \
 SOURCE+= pkgcache.cc version.cc fileutl.cc pkgcachegen.cc depcache.cc \
          orderlist.cc tagfile.cc sourcelist.cc packagemanager.cc \
          orderlist.cc tagfile.cc sourcelist.cc packagemanager.cc \
@@ -29,7 +29,7 @@ SOURCE+= deb/deblistparser.cc
 HEADERS = algorithms.h depcache.h mmap.h pkgcachegen.h cacheiterators.h \
 HEADERS = algorithms.h depcache.h mmap.h pkgcachegen.h cacheiterators.h \
           error.h orderlist.h sourcelist.h configuration.h fileutl.h \
           error.h orderlist.h sourcelist.h configuration.h fileutl.h \
           packagemanager.h tagfile.h deblistparser.h init.h pkgcache.h \
           packagemanager.h tagfile.h deblistparser.h init.h pkgcache.h \
-          version.h
+          version.h progress.h
 HEADERS := $(addprefix apt-pkg/,$(HEADERS))
 HEADERS := $(addprefix apt-pkg/,$(HEADERS))
 
 
 # Private header files
 # Private header files

+ 6 - 2
apt-pkg/pkgcachegen.cc

@@ -1,6 +1,6 @@
 // -*- mode: cpp; mode: fold -*-
 // -*- mode: cpp; mode: fold -*-
 // Description								/*{{{*/
 // Description								/*{{{*/
-// $Id: pkgcachegen.cc,v 1.11 1998/07/19 04:22:02 jgg Exp $
+// $Id: pkgcachegen.cc,v 1.12 1998/07/21 05:33:19 jgg Exp $
 /* ######################################################################
 /* ######################################################################
    
    
    Package Cache Generator - Generator for the cache structure.
    Package Cache Generator - Generator for the cache structure.
@@ -26,7 +26,8 @@
 // CacheGenerator::pkgCacheGenerator - Constructor			/*{{{*/
 // CacheGenerator::pkgCacheGenerator - Constructor			/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* We set the diry flag and make sure that is written to the disk */
 /* We set the diry flag and make sure that is written to the disk */
-pkgCacheGenerator::pkgCacheGenerator(DynamicMMap &Map) : Map(Map), Cache(Map)
+pkgCacheGenerator::pkgCacheGenerator(DynamicMMap &Map,OpProgress &Prog) :
+                    Map(Map), Cache(Map), Progress(Prog)
 {
 {
    if (_error->PendingError() == true)
    if (_error->PendingError() == true)
       return;
       return;
@@ -71,6 +72,7 @@ bool pkgCacheGenerator::MergeList(ListParser &List)
       pkgCache::PkgIterator Pkg;
       pkgCache::PkgIterator Pkg;
       if (NewPackage(Pkg,PackageName) == false)
       if (NewPackage(Pkg,PackageName) == false)
 	 return false;
 	 return false;
+      Progress.Progress(List.Offset());
       
       
       /* Get a pointer to the version structure. We know the list is sorted
       /* Get a pointer to the version structure. We know the list is sorted
          so we use that fact in the search. Insertion of new versions is
          so we use that fact in the search. Insertion of new versions is
@@ -318,6 +320,8 @@ bool pkgCacheGenerator::SelectFile(string File,unsigned long Flags)
    
    
    if (CurrentFile->FileName == 0)
    if (CurrentFile->FileName == 0)
       return false;
       return false;
+   
+   Progress.SubProgress(Buf.st_size,File);
    return true;
    return true;
 }
 }
 									/*}}}*/
 									/*}}}*/

+ 5 - 3
apt-pkg/pkgcachegen.h

@@ -1,6 +1,6 @@
 // -*- mode: cpp; mode: fold -*-
 // -*- mode: cpp; mode: fold -*-
 // Description								/*{{{*/
 // Description								/*{{{*/
-// $Id: pkgcachegen.h,v 1.7 1998/07/19 21:24:14 jgg Exp $
+// $Id: pkgcachegen.h,v 1.8 1998/07/21 05:33:20 jgg Exp $
 /* ######################################################################
 /* ######################################################################
    
    
    Package Cache Generator - Generator for the cache structure.
    Package Cache Generator - Generator for the cache structure.
@@ -25,6 +25,7 @@
 #endif 
 #endif 
 
 
 #include <apt-pkg/pkgcache.h>
 #include <apt-pkg/pkgcache.h>
+#include <apt-pkg/progress.h>
 
 
 class pkgCacheGenerator
 class pkgCacheGenerator
 {
 {
@@ -36,7 +37,8 @@ class pkgCacheGenerator
    
    
    DynamicMMap &Map;
    DynamicMMap &Map;
    pkgCache Cache;
    pkgCache Cache;
-
+   OpProgress &Progress;
+   
    string PkgFileName;
    string PkgFileName;
    pkgCache::PackageFile *CurrentFile;
    pkgCache::PackageFile *CurrentFile;
    
    
@@ -87,7 +89,7 @@ class pkgCacheGenerator
    bool MergeList(ListParser &List);
    bool MergeList(ListParser &List);
    inline pkgCache &GetCache() {return Cache;};
    inline pkgCache &GetCache() {return Cache;};
       
       
-   pkgCacheGenerator(DynamicMMap &Map);
+   pkgCacheGenerator(DynamicMMap &Map,OpProgress &Progress);
    ~pkgCacheGenerator();
    ~pkgCacheGenerator();
 };
 };
 
 

+ 8 - 5
cmdline/apt-cache.cc

@@ -1,6 +1,6 @@
 // -*- mode: cpp; mode: fold -*-
 // -*- mode: cpp; mode: fold -*-
 // Description								/*{{{*/
 // Description								/*{{{*/
-// $Id: apt-cache.cc,v 1.4 1998/07/19 04:42:18 jgg Exp $
+// $Id: apt-cache.cc,v 1.5 1998/07/21 05:33:21 jgg Exp $
 /* ######################################################################
 /* ######################################################################
    
    
    apt-cache - Manages the cache file.
    apt-cache - Manages the cache file.
@@ -28,6 +28,7 @@
 #include <apt-pkg/pkgcachegen.h>
 #include <apt-pkg/pkgcachegen.h>
 #include <apt-pkg/deblistparser.h>
 #include <apt-pkg/deblistparser.h>
 #include <apt-pkg/init.h>
 #include <apt-pkg/init.h>
+#include <apt-pkg/progress.h>
 
 
 #include <iostream.h>
 #include <iostream.h>
 #include <fstream.h>
 #include <fstream.h>
@@ -267,16 +268,17 @@ bool DoAdd(int argc,char *argv[])
    DynamicMMap Map(CacheF,MMap::Public);
    DynamicMMap Map(CacheF,MMap::Public);
    if (_error->PendingError() == true)
    if (_error->PendingError() == true)
       return false;
       return false;
-   
-   pkgCacheGenerator Gen(Map);
+
+   OpTextProgress Progress;
+   pkgCacheGenerator Gen(Map,Progress);
    if (_error->PendingError() == true)
    if (_error->PendingError() == true)
       return false;
       return false;
 
 
    for (int I = 0; I != argc; I++)
    for (int I = 0; I != argc; I++)
    {
    {
+      Progress.OverallProgress(I,argc,1,"Generating cache");
       if (SplitArg(argv[I],FileName,Dist,Ver) == false)
       if (SplitArg(argv[I],FileName,Dist,Ver) == false)
 	 return false;
 	 return false;
-      cout << FileName << endl;
       
       
       // Do the merge
       // Do the merge
       FileFd TagF(FileName.c_str(),FileFd::ReadOnly);
       FileFd TagF(FileName.c_str(),FileFd::ReadOnly);
@@ -290,7 +292,8 @@ bool DoAdd(int argc,char *argv[])
       if (Gen.MergeList(Parser) == false)
       if (Gen.MergeList(Parser) == false)
 	 return _error->Error("Problem with MergeList");
 	 return _error->Error("Problem with MergeList");
    }
    }
-   
+
+   Progress.Done();
    Stats(Gen.GetCache());
    Stats(Gen.GetCache());
    
    
    return true;
    return true;