]> git.saurik.com Git - apt.git/commitdiff
Support for memory-only caching
authorArch Librarian <arch@canonical.com>
Mon, 20 Sep 2004 16:53:34 +0000 (16:53 +0000)
committerArch Librarian <arch@canonical.com>
Mon, 20 Sep 2004 16:53:34 +0000 (16:53 +0000)
Author: jgg
Date: 1999-04-18 06:36:36 GMT
Support for memory-only caching

apt-pkg/cachefile.cc [new file with mode: 0644]
apt-pkg/cachefile.h [new file with mode: 0644]
apt-pkg/contrib/mmap.cc
apt-pkg/contrib/mmap.h
apt-pkg/deb/dpkginit.cc
apt-pkg/makefile
apt-pkg/pkgcachegen.cc
apt-pkg/pkgcachegen.h
cmdline/apt-get.cc

diff --git a/apt-pkg/cachefile.cc b/apt-pkg/cachefile.cc
new file mode 100644 (file)
index 0000000..285eb31
--- /dev/null
@@ -0,0 +1,96 @@
+// -*- mode: cpp; mode: fold -*-
+// Description                                                         /*{{{*/
+// $Id: cachefile.cc,v 1.1 1999/04/18 06:36:36 jgg Exp $
+/* ######################################################################
+   
+   CacheFile - Simple wrapper class for opening, generating and whatnot
+   
+   This class implements a simple 2 line mechanism to open various sorts
+   of caches. It can operate as root, as not root, show progress and so on,
+   it transparently handles everything necessary.
+   
+   ##################################################################### */
+                                                                       /*}}}*/
+// Include Files                                                       /*{{{*/
+#ifdef __GNUG__
+#pragma implementation "apt-pkg/cachefile.h"
+#endif
+
+#include <apt-pkg/cachefile.h>
+#include <apt-pkg/error.h>
+#include <apt-pkg/sourcelist.h>
+#include <apt-pkg/pkgcachegen.h>
+#include <apt-pkg/configuration.h>
+                                                                       /*}}}*/
+
+// CacheFile::CacheFile - Constructor                                  /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+pkgCacheFile::pkgCacheFile() : Map(0), Cache(0), Lock() 
+{
+}
+                                                                       /*}}}*/
+// CacheFile::~CacheFile - Destructor                                          /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+pkgCacheFile::~pkgCacheFile()
+{
+   delete Cache;
+   delete Map;
+   delete Lock;
+}   
+                                                                       /*}}}*/
+// CacheFile::Open - Open the cache files, creating if necessary       /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool pkgCacheFile::Open(OpProgress &Progress,bool WithLock)
+{
+   if (WithLock == true)
+      Lock = new pkgDpkgLock;
+   
+   if (_error->PendingError() == true)
+      return false;
+   
+   // Read the source list
+   pkgSourceList List;
+   if (List.ReadMainList() == false)
+      return _error->Error("The list of sources could not be read.");
+   
+   /* Build all of the caches, using the cache files if we are locking 
+      (ie as root) */
+   if (WithLock == true)
+   {
+      pkgMakeStatusCache(List,Progress);
+      Progress.Done();
+      if (_error->PendingError() == true)
+        return _error->Error("The package lists or status file could not be parsed or opened.");
+      if (_error->empty() == false)
+        _error->Warning("You may want to run apt-get update to correct theses missing files");
+      
+      // Open the cache file
+      FileFd File(_config->FindFile("Dir::Cache::pkgcache"),FileFd::ReadOnly);
+      if (_error->PendingError() == true)
+        return false;
+      
+      Map = new MMap(File,MMap::Public | MMap::ReadOnly);
+      if (_error->PendingError() == true)
+        return false;
+   }
+   else
+   {
+      Map = pkgMakeStatusCacheMem(List,Progress);
+      Progress.Done();
+      if (Map == 0)
+        return false;
+   }
+   
+   // Create the dependency cache
+   Cache = new pkgDepCache(*Map,Progress);
+   if (_error->PendingError() == true)
+      return false;
+
+   Progress.Done();
+   
+   return true;
+}
+                                                                       /*}}}*/
diff --git a/apt-pkg/cachefile.h b/apt-pkg/cachefile.h
new file mode 100644 (file)
index 0000000..23bd400
--- /dev/null
@@ -0,0 +1,48 @@
+// -*- mode: cpp; mode: fold -*-
+// Description                                                         /*{{{*/
+// $Id: cachefile.h,v 1.1 1999/04/18 06:36:36 jgg Exp $
+/* ######################################################################
+   
+   CacheFile - Simple wrapper class for opening, generating and whatnot
+   
+   This class implements a simple 2 line mechanism to open various sorts
+   of caches. It can operate as root, as not root, show progress and so on,
+   it transparently handles everything necessary.
+   
+   ##################################################################### */
+                                                                       /*}}}*/
+#ifndef PKGLIB_CACHEFILE_H
+#define PKGLIB_CACHEFILE_H
+
+#ifdef __GNUG__
+#pragma interface "apt-pkg/cachefile.h"
+#endif 
+
+#include <apt-pkg/depcache.h>
+#include <apt-pkg/dpkginit.h>
+
+class pkgCacheFile
+{
+   protected:
+   
+   MMap *Map;
+   pkgDepCache *Cache;
+   pkgDpkgLock *Lock;
+   
+   public:
+      
+   // We look pretty much exactly like a pointer to a dep cache
+   inline operator pkgDepCache &() {return *Cache;};
+   inline pkgDepCache *operator ->() {return Cache;};
+   inline pkgDepCache &operator *() {return *Cache;};
+
+   // Release the dpkg status lock
+   inline void ReleaseLock() {Lock->Close();};
+   
+   bool Open(OpProgress &Progress,bool WithLock = true);
+   
+   pkgCacheFile();
+   ~pkgCacheFile();
+};
+
+#endif
index 7a5065ffb219452ffef42c41a3eaef8be0f09e23..098c61ca6efe2bde9880537841673f1669171e95 100644 (file)
@@ -1,6 +1,6 @@
 // -*- mode: cpp; mode: fold -*-
 // Description                                                         /*{{{*/
-// $Id: mmap.cc,v 1.14 1999/03/18 04:32:46 jgg Exp $
+// $Id: mmap.cc,v 1.15 1999/04/18 06:36:36 jgg Exp $
 /* ######################################################################
    
    MMap Class - Provides 'real' mmap or a faked mmap using read().
 // MMap::MMap - Constructor                                            /*{{{*/
 // ---------------------------------------------------------------------
 /* */
-MMap::MMap(FileFd &F,unsigned long Flags) : Fd(F), Flags(Flags), iSize(0),
+MMap::MMap(FileFd &F,unsigned long Flags) : Flags(Flags), iSize(0),
                      Base(0)
 {
    if ((Flags & NoImmMap) != NoImmMap)
-      Map();
+      Map(F);
+}
+                                                                       /*}}}*/
+// MMap::MMap - Constructor                                            /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+MMap::MMap(unsigned long Flags) : Flags(Flags), iSize(0),
+                     Base(0)
+{
 }
                                                                        /*}}}*/
 // MMap::~MMap - Destructor                                            /*{{{*/
@@ -50,13 +58,13 @@ MMap::MMap(FileFd &F,unsigned long Flags) : Fd(F), Flags(Flags), iSize(0),
 /* */
 MMap::~MMap()
 {
-   Close(true);
+   Close();
 }
                                                                        /*}}}*/
 // MMap::Map - Perform the mapping                                     /*{{{*/
 // ---------------------------------------------------------------------
 /* */
-bool MMap::Map()
+bool MMap::Map(FileFd &Fd)
 {
    iSize = Fd.Size();
    
@@ -82,11 +90,11 @@ bool MMap::Map()
 // MMap::Close - Close the map                                         /*{{{*/
 // ---------------------------------------------------------------------
 /* */
-bool MMap::Close(bool DoClose, bool DoSync)
+bool MMap::Close(bool DoSync)
 {
-   if (Fd.IsOpen() == false)
+   if ((Flags & UnMapped) == UnMapped || Base == 0 || iSize == 0)
       return true;
-
+   
    if (DoSync == true)
       Sync();
    
@@ -94,8 +102,6 @@ bool MMap::Close(bool DoClose, bool DoSync)
       _error->Warning("Unable to munmap");
    
    iSize = 0;
-   if (DoClose == true)
-      Fd.Close();
    return true;
 }
                                                                        /*}}}*/
@@ -105,6 +111,9 @@ bool MMap::Close(bool DoClose, bool DoSync)
    not return till all IO is complete */
 bool MMap::Sync()
 {   
+   if ((Flags & UnMapped) == UnMapped)
+      return true;
+   
 #ifdef _POSIX_SYNCHRONIZED_IO   
    if ((Flags & ReadOnly) != ReadOnly)
       if (msync((char *)Base,iSize,MS_SYNC) != 0)
@@ -118,6 +127,9 @@ bool MMap::Sync()
 /* */
 bool MMap::Sync(unsigned long Start,unsigned long Stop)
 {
+   if ((Flags & UnMapped) == UnMapped)
+      return true;
+   
 #ifdef _POSIX_SYNCHRONIZED_IO
    unsigned long PSize = sysconf(_SC_PAGESIZE);
    if ((Flags & ReadOnly) != ReadOnly)
@@ -132,30 +144,49 @@ bool MMap::Sync(unsigned long Start,unsigned long Stop)
 // ---------------------------------------------------------------------
 /* */
 DynamicMMap::DynamicMMap(FileFd &F,unsigned long Flags,unsigned long WorkSpace) : 
-             MMap(F,Flags | NoImmMap), WorkSpace(WorkSpace)
+             MMap(F,Flags | NoImmMap), Fd(&F), WorkSpace(WorkSpace)
 {
    if (_error->PendingError() == true)
       return;
    
-   unsigned long EndOfFile = Fd.Size();
-   Fd.Seek(WorkSpace);
+   unsigned long EndOfFile = Fd->Size();
+   Fd->Seek(WorkSpace);
    char C = 0;
-   Fd.Write(&C,sizeof(C));
-   Map();
+   Fd->Write(&C,sizeof(C));
+   Map(F);
    iSize = EndOfFile;
 }
                                                                        /*}}}*/
+// DynamicMMap::DynamicMMap - Constructor for a non-file backed map    /*{{{*/
+// ---------------------------------------------------------------------
+/* This is just a fancy malloc really.. */
+DynamicMMap::DynamicMMap(unsigned long Flags,unsigned long WorkSpace) :
+             MMap(Flags | NoImmMap | UnMapped), Fd(0), WorkSpace(WorkSpace)
+{
+   if (_error->PendingError() == true)
+      return;
+   
+   Base = new unsigned char[WorkSpace];
+   iSize = 0;
+}
+                                                                       /*}}}*/
 // DynamicMMap::~DynamicMMap - Destructor                              /*{{{*/
 // ---------------------------------------------------------------------
 /* We truncate the file to the size of the memory data set */
 DynamicMMap::~DynamicMMap()
 {
+   if (Fd == 0)
+   {
+      delete [] (unsigned char *)Base;
+      return;
+   }
+   
    unsigned long EndOfFile = iSize;
    Sync();
    iSize = WorkSpace;
-   Close(false,false);
-   ftruncate(Fd.Fd(),EndOfFile);
-   Fd.Close();
+   Close(false);
+   ftruncate(Fd->Fd(),EndOfFile);
+   Fd->Close();
 }  
                                                                        /*}}}*/
 // DynamicMMap::RawAllocate - Allocate a raw chunk of unaligned space  /*{{{*/
index 3cb6c646898a51c09001a2f3e4e39d7d3320c5e2..0c11d32021af8c22d848bcb0580e3b6cbb756450 100644 (file)
@@ -1,6 +1,6 @@
 // -*- mode: cpp; mode: fold -*-
 // Description                                                         /*{{{*/
-// $Id: mmap.h,v 1.8 1999/01/18 06:20:08 jgg Exp $
+// $Id: mmap.h,v 1.9 1999/04/18 06:36:36 jgg Exp $
 /* ######################################################################
    
    MMap Class - Provides 'real' mmap or a faked mmap using read().
@@ -36,17 +36,17 @@ class MMap
 {
    protected:
    
-   FileFd &Fd;
-   unsigned long Flags;   
+   unsigned long Flags;
    unsigned long iSize;
    void *Base;
 
-   bool Map();
-   bool Close(bool DoClose = true,bool DoSync = true);
+   bool Map(FileFd &Fd);
+   bool Close(bool DoSync = true);
    
    public:
 
-   enum OpenFlags {NoImmMap = (1<<0),Public = (1<<1),ReadOnly = (1<<2)};
+   enum OpenFlags {NoImmMap = (1<<0),Public = (1<<1),ReadOnly = (1<<2),
+                   UnMapped = (1<<3)};
       
    // Simple accessors
    inline operator void *() {return Base;};
@@ -58,6 +58,7 @@ class MMap
    bool Sync(unsigned long Start,unsigned long Stop);
    
    MMap(FileFd &F,unsigned long Flags);
+   MMap(unsigned long Flags);
    virtual ~MMap();
 };
 
@@ -75,6 +76,7 @@ class DynamicMMap : public MMap
    
    protected:
    
+   FileFd *Fd;
    unsigned long WorkSpace;
    Pool *Pools;
    unsigned int PoolCount;
@@ -89,6 +91,7 @@ class DynamicMMap : public MMap
    void UsePools(Pool &P,unsigned int Count) {Pools = &P; PoolCount = Count;}; 
    
    DynamicMMap(FileFd &F,unsigned long Flags,unsigned long WorkSpace = 2*1024*1024);
+   DynamicMMap(unsigned long Flags,unsigned long WorkSpace = 2*1024*1024);
    virtual ~DynamicMMap();
 };
 
index 095156d0dc4df95fe15a61fee506cc617f7d725f..518d18f59e7964e40fdb0415db1769870226317b 100644 (file)
@@ -1,6 +1,6 @@
 // -*- mode: cpp; mode: fold -*-
 // Description                                                         /*{{{*/
-// $Id: dpkginit.cc,v 1.1 1998/11/23 07:03:10 jgg Exp $
+// $Id: dpkginit.cc,v 1.2 1999/04/18 06:36:36 jgg Exp $
 /* ######################################################################
 
    DPKG init - Initialize the dpkg stuff
@@ -54,8 +54,8 @@ bool pkgDpkgLock::GetLock()
    string AdminDir = flNotFile(_config->Find("Dir::State::status"));
    LockFD = ::GetLock(AdminDir + "lock");
    if (LockFD == -1)
-      return _error->Errno("Open","Unable to lock the administration directory "
-                          "%s, are you root?",AdminDir.c_str());
+      return _error->Error("Unable to lock the administration directory, "
+                          "are you root?");
    
    // Check for updates.. (dirty)
    string File = AdminDir + "updates/";
index 14ed1dea599778a670b04a72ef6804ac0a258814..80bfbdcf3f042a94084dc73ab7686c10b53b1d5b 100644 (file)
@@ -25,7 +25,7 @@ SOURCE+= pkgcache.cc version.cc fileutl.cc pkgcachegen.cc depcache.cc \
          orderlist.cc tagfile.cc sourcelist.cc packagemanager.cc \
         pkgrecords.cc algorithms.cc acquire.cc acquire-item.cc \
         acquire-worker.cc acquire-method.cc init.cc clean.cc \
-        srcrecords.cc
+        srcrecords.cc cachefile.cc
 
 # Source code for the debian specific components
 SOURCE+= deb/deblistparser.cc deb/debrecords.cc deb/dpkgpm.cc deb/dpkginit.cc \
@@ -38,7 +38,7 @@ HEADERS = algorithms.h depcache.h mmap.h pkgcachegen.h cacheiterators.h \
           version.h progress.h pkgrecords.h debrecords.h cmndline.h \
          acquire.h acquire-worker.h acquire-item.h acquire-method.h md5.h \
          dpkgpm.h dpkginit.h cdromutl.h strutl.h clean.h srcrecords.h \
-         debsrcrecords.h
+         debsrcrecords.h cachefile.h
 
 HEADERS := $(addprefix apt-pkg/,$(HEADERS))
 
index d7e830df544114741c88b0a73c3088b86383a93a..ee65c94d1c707ed5b7b1893a953921533dcc0361 100644 (file)
@@ -1,6 +1,6 @@
 // -*- mode: cpp; mode: fold -*-
 // Description                                                         /*{{{*/
-// $Id: pkgcachegen.cc,v 1.34 1999/04/04 01:33:09 jgg Exp $
+// $Id: pkgcachegen.cc,v 1.35 1999/04/18 06:36:36 jgg Exp $
 /* ######################################################################
    
    Package Cache Generator - Generator for the cache structure.
@@ -615,6 +615,70 @@ static bool pkgMergeStatus(OpProgress &Progress,pkgCacheGenerator &Gen,
       Progress.Progress(Pkg.Size());
    }
    
+   return true;
+}
+                                                                       /*}}}*/
+// GenerateSrcCache - Write the source package lists to the map                /*{{{*/
+// ---------------------------------------------------------------------
+/* This puts the source package cache into the given generator. */
+bool pkgGenerateSrcCache(pkgSourceList &List,OpProgress &Progress,
+                        pkgCacheGenerator &Gen,
+                        unsigned long &CurrentSize,unsigned long TotalSize)
+{
+   string ListDir = _config->FindDir("Dir::State::lists");
+   
+   // Prepare the progress indicator
+   TotalSize = 0;
+   struct stat Buf;
+   for (pkgSourceList::const_iterator I = List.begin(); I != List.end(); I++)
+   {
+      string File = ListDir + URItoFileName(I->PackagesURI());
+      if (stat(File.c_str(),&Buf) != 0)
+        continue;
+      TotalSize += Buf.st_size;
+   }
+   
+   if (pkgAddSourcesSize(TotalSize) == false)
+      return false;
+   
+   // Generate the pkg source cache
+   CurrentSize = 0;
+   for (pkgSourceList::const_iterator I = List.begin(); I != List.end(); I++)
+   {
+      // Only cache deb source types.
+      if (I->Type != pkgSourceList::Item::Deb)
+        continue;
+      
+      string File = ListDir + URItoFileName(I->PackagesURI());
+      
+      if (FileExists(File) == false)
+        continue;
+      
+      FileFd Pkg(File,FileFd::ReadOnly);
+      debListParser Parser(Pkg);
+      Progress.OverallProgress(CurrentSize,TotalSize,Pkg.Size(),"Reading Package Lists");
+      if (_error->PendingError() == true)
+        return _error->Error("Problem opening %s",File.c_str());
+      CurrentSize += Pkg.Size();
+      
+      Progress.SubProgress(0,I->PackagesInfo());
+      if (Gen.SelectFile(File) == false)
+        return _error->Error("Problem with SelectFile %s",File.c_str());
+      
+      if (Gen.MergeList(Parser) == false)
+        return _error->Error("Problem with MergeList %s",File.c_str());
+      
+      // Check the release file
+      string RFile = ListDir + URItoFileName(I->ReleaseURI());
+      if (FileExists(RFile) == true)
+      {
+        FileFd Rel(RFile,FileFd::ReadOnly);
+        if (_error->PendingError() == true)
+           return false;
+        Parser.LoadReleaseInfo(Gen.GetCurFile(),Rel);
+      }
+   }
+   
    return true;
 }
                                                                        /*}}}*/
@@ -634,67 +698,18 @@ bool pkgMakeStatusCache(pkgSourceList &List,OpProgress &Progress)
    if (SrcOk == false)
    {      
       string SCacheFile = _config->FindFile("Dir::Cache::srcpkgcache");
-      string ListDir = _config->FindDir("Dir::State::lists");
       FileFd SCacheF(SCacheFile,FileFd::WriteEmpty);
       FileFd CacheF(CacheFile,FileFd::WriteEmpty);
       DynamicMMap Map(CacheF,MMap::Public);
       if (_error->PendingError() == true)
         return false;
-      
+
       pkgCacheGenerator Gen(Map,Progress);
-      
-      // Prepare the progress indicator
+      unsigned long CurrentSize = 0;
       unsigned long TotalSize = 0;
-      struct stat Buf;
-      for (pkgSourceList::const_iterator I = List.begin(); I != List.end(); I++)
-      {
-        string File = ListDir + URItoFileName(I->PackagesURI());
-        if (stat(File.c_str(),&Buf) != 0)
-           continue;
-        TotalSize += Buf.st_size;
-      }
-      
-      if (pkgAddSourcesSize(TotalSize) == false)
+      if (pkgGenerateSrcCache(List,Progress,Gen,CurrentSize,TotalSize) == false)
         return false;
       
-      // Generate the pkg source cache
-      unsigned long CurrentSize = 0;
-      for (pkgSourceList::const_iterator I = List.begin(); I != List.end(); I++)
-      {
-        // Only cache deb source types.
-        if (I->Type != pkgSourceList::Item::Deb)
-           continue;
-        
-        string File = ListDir + URItoFileName(I->PackagesURI());
-        
-        if (FileExists(File) == false)
-           continue;
-        
-        FileFd Pkg(File,FileFd::ReadOnly);
-        debListParser Parser(Pkg);
-        Progress.OverallProgress(CurrentSize,TotalSize,Pkg.Size(),"Reading Package Lists");
-        if (_error->PendingError() == true)
-           return _error->Error("Problem opening %s",File.c_str());
-        CurrentSize += Pkg.Size();
-
-        Progress.SubProgress(0,I->PackagesInfo());
-        if (Gen.SelectFile(File) == false)
-           return _error->Error("Problem with SelectFile %s",File.c_str());
-        
-        if (Gen.MergeList(Parser) == false)
-           return _error->Error("Problem with MergeList %s",File.c_str());
-
-        // Check the release file
-        string RFile = ListDir + URItoFileName(I->ReleaseURI());
-        if (FileExists(RFile) == true)
-        {
-           FileFd Rel(RFile,FileFd::ReadOnly);
-           if (_error->PendingError() == true)
-              return false;
-           Parser.LoadReleaseInfo(Gen.GetCurFile(),Rel);
-        }
-      }               
-      
       // Write the src cache
       Gen.GetCache().HeaderP->Dirty = false;
       if (SCacheF.Write(Map.Data(),Map.Size()) == false)
@@ -736,3 +751,124 @@ bool pkgMakeStatusCache(pkgSourceList &List,OpProgress &Progress)
    return pkgMergeStatus(Progress,Gen,CurrentSize,TotalSize);
 }
                                                                        /*}}}*/
+// MakeStatusCacheMem - Returns a map for the status cache             /*{{{*/
+// ---------------------------------------------------------------------
+/* This creates a map object for the status cache. If the process has write
+   access to the caches then it is the same as MakeStatusCache, otherwise it
+   creates a memory block and puts the cache in there. */
+MMap *pkgMakeStatusCacheMem(pkgSourceList &List,OpProgress &Progress)
+{
+   /* If the cache file is writeable this is just a wrapper for
+      MakeStatusCache */
+   string CacheFile = _config->FindFile("Dir::Cache::pkgcache");
+   bool Writeable = access(CacheFile.c_str(),W_OK) == 0;
+   if (Writeable == true)
+   {
+      if (pkgMakeStatusCache(List,Progress) == false)
+        return 0;
+      
+      // Open the cache file
+      FileFd File(_config->FindFile("Dir::Cache::pkgcache"),FileFd::ReadOnly);
+      if (_error->PendingError() == true)
+        return 0;
+      
+      MMap *Map = new MMap(File,MMap::Public | MMap::ReadOnly);
+      if (_error->PendingError() == true)
+      {
+        delete Map;
+        return 0;
+      }
+      return Map;
+   }      
+
+   // Mostly from MakeStatusCache..
+   Progress.OverallProgress(0,1,1,"Reading Package Lists");
+   
+   bool SrcOk = pkgSrcCacheCheck(List);
+   bool PkgOk = SrcOk && pkgPkgCacheCheck(CacheFile);
+                          
+   // Rebuild the source and package caches   
+   if (SrcOk == false)
+   {
+      DynamicMMap *Map = new DynamicMMap(MMap::Public);
+      if (_error->PendingError() == true)
+      {
+        delete Map;
+        return 0;
+      }
+      
+      pkgCacheGenerator Gen(*Map,Progress);
+      unsigned long CurrentSize = 0;
+      unsigned long TotalSize = 0;
+      if (pkgGenerateSrcCache(List,Progress,Gen,CurrentSize,TotalSize) == false)
+      {
+        delete Map;
+        return 0;
+      }
+      
+      // Merge in the source caches
+      if (pkgMergeStatus(Progress,Gen,CurrentSize,TotalSize) == false)
+      {
+        delete Map;
+        return 0;
+      }
+      
+      return Map;
+   }
+
+   if (PkgOk == true)
+   {
+      Progress.OverallProgress(1,1,1,"Reading Package Lists");
+      
+      // Open the cache file
+      FileFd File(_config->FindFile("Dir::Cache::pkgcache"),FileFd::ReadOnly);
+      if (_error->PendingError() == true)
+        return 0;
+      
+      MMap *Map = new MMap(File,MMap::Public | MMap::ReadOnly);
+      if (_error->PendingError() == true)
+      {
+        delete Map;
+        return 0;
+      }
+      return Map;
+   }
+   
+   // We use the source cache to generate the package cache
+   string SCacheFile = _config->FindFile("Dir::Cache::srcpkgcache");
+   FileFd SCacheF(SCacheFile,FileFd::ReadOnly);
+   DynamicMMap *Map = new DynamicMMap(MMap::Public);
+   if (_error->PendingError() == true)
+   {
+      delete Map;
+      return 0;
+   }
+   
+   // Preload the map with the source cache
+   if (SCacheF.Read((unsigned char *)Map->Data() + Map->RawAllocate(SCacheF.Size()),
+                   SCacheF.Size()) == false)
+   {
+      delete Map;
+      return 0;
+   }
+      
+   pkgCacheGenerator Gen(*Map,Progress);
+   
+   // Compute the progress
+   unsigned long TotalSize = 0;
+   if (pkgAddSourcesSize(TotalSize) == false)
+   {
+      delete Map;
+      return 0;
+   }
+
+   unsigned long CurrentSize = 0;
+   if (pkgMergeStatus(Progress,Gen,CurrentSize,TotalSize) == false)
+   {
+      delete Map;
+      return 0;
+   }
+    
+   return Map;
+}
+                                                                       /*}}}*/
index 8ffb277c6e7feec8f690797dca26bdd571dcd7d6..66a9913713b8d27b35c65d7f1bd7a94a8e7fe0f4 100644 (file)
@@ -1,6 +1,6 @@
 // -*- mode: cpp; mode: fold -*-
 // Description                                                         /*{{{*/
-// $Id: pkgcachegen.h,v 1.12 1999/02/23 06:46:24 jgg Exp $
+// $Id: pkgcachegen.h,v 1.13 1999/04/18 06:36:36 jgg Exp $
 /* ######################################################################
    
    Package Cache Generator - Generator for the cache structure.
@@ -28,6 +28,7 @@
 
 class pkgSourceList;
 class OpProgress;
+class MMap;
 
 class pkgCacheGenerator
 {
@@ -71,6 +72,7 @@ class pkgCacheGenerator
 bool pkgSrcCacheCheck(pkgSourceList &List);
 bool pkgPkgCacheCheck(string CacheFile);
 bool pkgMakeStatusCache(pkgSourceList &List,OpProgress &Progress);
+MMap *pkgMakeStatusCacheMem(pkgSourceList &List,OpProgress &Progress);
 
 // This is the abstract package list parser class.
 class pkgCacheGenerator::ListParser
index a2c0132069fe219deb6f974981a91772a63e1874..07ba19f18aa6e153055e1946c20b0e3564736fcc 100644 (file)
@@ -1,6 +1,6 @@
 // -*- mode: cpp; mode: fold -*-
 // Description                                                         /*{{{*/
-// $Id: apt-get.cc,v 1.51 1999/04/12 02:25:25 jgg Exp $
+// $Id: apt-get.cc,v 1.52 1999/04/18 06:36:36 jgg Exp $
 /* ######################################################################
    
    apt-get - Cover for dpkg
 #include <apt-pkg/init.h>
 #include <apt-pkg/depcache.h>
 #include <apt-pkg/sourcelist.h>
-#include <apt-pkg/pkgcachegen.h>
 #include <apt-pkg/algorithms.h>
 #include <apt-pkg/acquire-item.h>
 #include <apt-pkg/dpkgpm.h>
-#include <apt-pkg/dpkginit.h>
 #include <apt-pkg/strutl.h>
 #include <apt-pkg/clean.h>
 #include <apt-pkg/srcrecords.h>
 #include <apt-pkg/version.h>
+#include <apt-pkg/cachefile.h>
 
 #include <config.h>
 
@@ -372,70 +371,27 @@ void Stats(ostream &out,pkgDepCache &Dep)
 // class CacheFile - Cover class for some dependency cache functions   /*{{{*/
 // ---------------------------------------------------------------------
 /* */
-class CacheFile
+class CacheFile : public pkgCacheFile
 {
    public:
    
-   FileFd *File;
-   MMap *Map;
-   pkgDepCache *Cache;
-   pkgDpkgLock Lock;
-   
-   inline operator pkgDepCache &() {return *Cache;};
-   inline pkgDepCache *operator ->() {return Cache;};
-   inline pkgDepCache &operator *() {return *Cache;};
-   
-   bool Open(bool AllowBroken = false);
-   CacheFile() : File(0), Map(0), Cache(0) {};
-   ~CacheFile()
+   bool CheckDeps(bool AllowBroken = false);
+   bool Open(bool WithLock = true) 
    {
-      delete Cache;
-      delete Map;
-      delete File;
-   }   
+      OpTextProgress Prog(*_config); 
+      return pkgCacheFile::Open(Prog,WithLock);
+   };
 };
                                                                        /*}}}*/
 // CacheFile::Open - Open the cache file                               /*{{{*/
 // ---------------------------------------------------------------------
 /* This routine generates the caches and then opens the dependency cache
    and verifies that the system is OK. */
-bool CacheFile::Open(bool AllowBroken)
+bool CacheFile::CheckDeps(bool AllowBroken)
 {
    if (_error->PendingError() == true)
       return false;
-   
-   // Create a progress class
-   OpTextProgress Progress(*_config);
-      
-   // Read the source list
-   pkgSourceList List;
-   if (List.ReadMainList() == false)
-      return _error->Error("The list of sources could not be read.");
-   
-   // Build all of the caches
-   pkgMakeStatusCache(List,Progress);
-   if (_error->PendingError() == true)
-      return _error->Error("The package lists or status file could not be parsed or opened.");
-   if (_error->empty() == false)
-      _error->Warning("You may want to run apt-get update to correct theses missing files");
-   
-   Progress.Done();
-   
-   // Open the cache file
-   File = new FileFd(_config->FindFile("Dir::Cache::pkgcache"),FileFd::ReadOnly);
-   if (_error->PendingError() == true)
-      return false;
-   
-   Map = new MMap(*File,MMap::Public | MMap::ReadOnly);
-   if (_error->PendingError() == true)
-      return false;
-   
-   Cache = new pkgDepCache(*Map,Progress);
-   if (_error->PendingError() == true)
-      return false;
 
-   Progress.Done();
-   
    // Check that the system is OK
    if (Cache->DelCount() != 0 || Cache->InstCount() != 0)
       return _error->Error("Internal Error, non-zero counts");
@@ -676,7 +632,7 @@ bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask = true,bool Saftey =
       return _error->Error("Aborting Install.");
    }
    
-   Cache.Lock.Close();
+   Cache.ReleaseLock();
    return PM.DoInstall();
 }
                                                                        /*}}}*/
@@ -724,7 +680,7 @@ bool DoUpdate(CommandLine &)
    
    // Prepare the cache.   
    CacheFile Cache;
-   if (Cache.Open() == false)
+   if (Cache.Open() == false || Cache.CheckDeps() == false)
       return false;
    
    return true;
@@ -737,7 +693,7 @@ bool DoUpdate(CommandLine &)
 bool DoUpgrade(CommandLine &CmdL)
 {
    CacheFile Cache;
-   if (Cache.Open() == false)
+   if (Cache.Open() == false || Cache.CheckDeps() == false)
       return false;
 
    // Do the upgrade
@@ -756,7 +712,7 @@ bool DoUpgrade(CommandLine &CmdL)
 bool DoInstall(CommandLine &CmdL)
 {
    CacheFile Cache;
-   if (Cache.Open(CmdL.FileSize() != 1) == false)
+   if (Cache.Open() == false || Cache.CheckDeps(CmdL.FileSize() != 1) == false)
       return false;
    
    // Enter the special broken fixing mode if the user specified arguments
@@ -949,7 +905,7 @@ bool DoInstall(CommandLine &CmdL)
 bool DoDistUpgrade(CommandLine &CmdL)
 {
    CacheFile Cache;
-   if (Cache.Open() == false)
+   if (Cache.Open() == false || Cache.CheckDeps() == false)
       return false;
 
    c0out << "Calculating Upgrade... " << flush;
@@ -971,7 +927,7 @@ bool DoDistUpgrade(CommandLine &CmdL)
 bool DoDSelectUpgrade(CommandLine &CmdL)
 {
    CacheFile Cache;
-   if (Cache.Open() == false)
+   if (Cache.Open() == false || Cache.CheckDeps() == false)
       return false;
    
    // Install everything with the install flag set
@@ -1066,7 +1022,7 @@ class LogCleaner : public pkgArchiveCleaner
 bool DoAutoClean(CommandLine &CmdL)
 {
    CacheFile Cache;
-   if (Cache.Open(true) == false)
+   if (Cache.Open() == false)
       return false;
    
    LogCleaner Cleaner;
@@ -1083,19 +1039,23 @@ bool DoCheck(CommandLine &CmdL)
 {
    CacheFile Cache;
    Cache.Open();
+   Cache.CheckDeps();
    
    return true;
 }
                                                                        /*}}}*/
 // DoSource - Fetch a source archive                                   /*{{{*/
 // ---------------------------------------------------------------------
-/* */
+/* Fetch souce packages */
 bool DoSource(CommandLine &CmdL)
 {
    CacheFile Cache;
-   if (Cache.Open(true) == false)
+   if (Cache.Open(false) == false)
       return false;
 
+   if (CmdL.FileSize() <= 1)
+      return _error->Error("Must specify at least one package to fetch source for");
+   
    // Read the source list
    pkgSourceList List;
    if (List.ReadMainList() == false)