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

Optimizations
Author: jgg
Date: 1998-12-07 07:26:19 GMT
Optimizations

Arch Librarian лет назад: 22
Родитель
Сommit
c1a2237722
8 измененных файлов с 98 добавлено и 41 удалено
  1. 3 2
      apt-pkg/pkgcache.cc
  2. 2 2
      apt-pkg/pkgcache.h
  3. 17 8
      apt-pkg/pkgcachegen.cc
  4. 38 22
      apt-pkg/tagfile.cc
  5. 3 1
      apt-pkg/tagfile.h
  6. 4 0
      buildlib/defaults.mak
  7. 1 1
      buildlib/program.mak
  8. 30 5
      methods/http.cc

+ 3 - 2
apt-pkg/pkgcache.cc

@@ -1,6 +1,6 @@
 // -*- mode: cpp; mode: fold -*-
 // Description								/*{{{*/
-// $Id: pkgcache.cc,v 1.19 1998/12/04 22:56:52 jgg Exp $
+// $Id: pkgcache.cc,v 1.20 1998/12/07 07:26:19 jgg Exp $
 /* ######################################################################
    
    Package Cache - Accessor code for the cache
@@ -159,7 +159,8 @@ pkgCache::PkgIterator pkgCache::FindPkg(string Name)
    Package *Pkg = PkgP + HeaderP->HashTable[Hash(Name)];
    for (; Pkg != PkgP; Pkg = PkgP + Pkg->NextPackage)
    {
-      if (Pkg->Name != 0 && StrP + Pkg->Name == Name)
+      if (Pkg->Name != 0 && StrP[Pkg->Name] == Name[0] &&
+	  StrP + Pkg->Name == Name)
 	 return PkgIterator(*this,Pkg);
    }
    return PkgIterator(*this,0);

+ 2 - 2
apt-pkg/pkgcache.h

@@ -1,6 +1,6 @@
 // -*- mode: cpp; mode: fold -*-
 // Description								/*{{{*/
-// $Id: pkgcache.h,v 1.10 1998/11/12 03:28:29 jgg Exp $
+// $Id: pkgcache.h,v 1.11 1998/12/07 07:26:20 jgg Exp $
 /* ######################################################################
    
    Cache - Structure definitions for the cache file
@@ -163,7 +163,7 @@ struct pkgCache::Header
    DynamicMMap::Pool Pools[7];
    
    // Rapid package name lookup
-   __apt_ptrloc HashTable[512];
+   __apt_ptrloc HashTable[2048];
 
    bool CheckSizes(Header &Against) const;
    Header();

+ 17 - 8
apt-pkg/pkgcachegen.cc

@@ -1,6 +1,6 @@
 // -*- mode: cpp; mode: fold -*-
 // Description								/*{{{*/
-// $Id: pkgcachegen.cc,v 1.23 1998/11/13 04:23:33 jgg Exp $
+// $Id: pkgcachegen.cc,v 1.24 1998/12/07 07:26:21 jgg Exp $
 /* ######################################################################
    
    Package Cache Generator - Generator for the cache structure.
@@ -253,19 +253,28 @@ bool pkgCacheGenerator::ListParser::NewDepends(pkgCache::VerIterator Ver,
 	 if ((Dep->Version = WriteString(Version)) == 0)
 	    return false;
    }
-   
+      
    // Link it to the package
    Dep->Package = Pkg.Index();
    Dep->NextRevDepends = Pkg->RevDepends;
    Pkg->RevDepends = Dep.Index();
    
-   // Link it to the version (at the end of the list)
-   __apt_ptrloc *Last = &Ver->DependsList;
-   for (pkgCache::DepIterator D = Ver.DependsList(); D.end() == false; D++)
-      Last = &D->NextDepends;
-   Dep->NextDepends = *Last;
-   *Last = Dep.Index();
+   /* Link it to the version (at the end of the list)
+      Caching the old end point speeds up generation substantially */
+   static pkgCache::VerIterator OldVer(Cache);
+   static __apt_ptrloc *OldLast;
+   if (OldVer != Ver)
+   {
+      OldLast = &Ver->DependsList;
+      for (pkgCache::DepIterator D = Ver.DependsList(); D.end() == false; D++)
+	 OldLast = &D->NextDepends;
+      OldVer = Ver;
+   }
    
+   Dep->NextDepends = *OldLast;
+   *OldLast = Dep.Index();
+   OldLast = &Dep->NextDepends;
+
    return true;
 }
 									/*}}}*/

+ 38 - 22
apt-pkg/tagfile.cc

@@ -1,6 +1,6 @@
 // -*- mode: cpp; mode: fold -*-
 // Description								/*{{{*/
-// $Id: tagfile.cc,v 1.16 1998/11/28 03:54:29 jgg Exp $
+// $Id: tagfile.cc,v 1.17 1998/12/07 07:26:22 jgg Exp $
 /* ######################################################################
 
    Fast scanner for RFC-822 type header information
@@ -115,38 +115,42 @@ bool pkgTagFile::Jump(pkgTagSection &Tag,unsigned long Offset)
 // TagSection::Scan - Scan for the end of the header information	/*{{{*/
 // ---------------------------------------------------------------------
 /* This looks for the first double new line in the data stream. It also
-   indexes the tags in the section. */
+   indexes the tags in the section. This very simple hash function for the
+   first 3 letters gives very good performance on the debian package files */
 bool pkgTagSection::Scan(const char *Start,unsigned long MaxLength)
 {
    const char *End = Start + MaxLength;
    Stop = Section = Start;
+   memset(AlphaIndexes,0,sizeof(AlphaIndexes));
    
    TagCount = 0;
-   Indexes[TagCount++] = Stop - Section;
-   Stop++;
-   for (; Stop < End; Stop++)
+   while (TagCount < sizeof(Indexes)/sizeof(Indexes[0]))
    {
-      if (Stop[-1] != '\n')
-	 continue;
+      if (isspace(Stop[0]) == 0)
+      {
+	 Indexes[TagCount++] = Stop - Section;
+	 unsigned char A = tolower(Stop[0]) - 'a';
+	 unsigned char B = tolower(Stop[1]) - 'a';
+	 unsigned char C = tolower(Stop[3]) - 'a';
+	 AlphaIndexes[((A + C/3)%26) + 26*((B + C/2)%26)] = TagCount;
+      }
 
-      // Skip line feeds
-      for (; Stop[0] == '\r' && Stop < End; Stop++);
+      Stop = (const char *)memchr(Stop,'\n',End - Stop);
       
-      if (Stop[0] == '\n')
+      if (Stop == 0)
+	 return false;
+      for (; Stop[1] == '\r' && Stop < End; Stop++);
+
+      if (Stop[1] == '\n')
       {
-	 // Extra one at the end to simplify find
 	 Indexes[TagCount] = Stop - Section;
 	 for (; (Stop[0] == '\n' || Stop[0] == '\r') && Stop < End; Stop++);
 	 return true;
       }
       
-      if (isspace(Stop[0]) == 0)
-	 Indexes[TagCount++] = Stop - Section;
-      
-      // Just in case.
-      if (TagCount > sizeof(Indexes)/sizeof(Indexes[0]))
-	 TagCount = sizeof(Indexes)/sizeof(Indexes[0]);
-   }   
+      Stop++;
+   }
+   
    return false;
 }
 									/*}}}*/
@@ -157,13 +161,24 @@ bool pkgTagSection::Find(const char *Tag,const char *&Start,
 		         const char *&End)
 {
    unsigned int Length = strlen(Tag);
-   for (unsigned int I = 0; I != TagCount; I++)
+   unsigned char A = tolower(Tag[0]) - 'a';
+   unsigned char B = tolower(Tag[1]) - 'a';
+   unsigned char C = tolower(Tag[3]) - 'a';
+   unsigned int I = AlphaIndexes[((A + C/3)%26) + 26*((B + C/2)%26)];
+   if (I == 0)
+      return false;
+   I--;
+   
+   for (unsigned int Counter = 0; Counter != TagCount; Counter++, 
+	I = (I+1)%TagCount)
    {
-      if (strncasecmp(Tag,Section + Indexes[I],Length) != 0)
+      const char *St;
+      St = Section + Indexes[I];
+      if (strncasecmp(Tag,St,Length) != 0)
 	 continue;
 
       // Make sure the colon is in the right place
-      const char *C = Section + Length + Indexes[I];
+      const char *C = St + Length;
       for (; isspace(*C) != 0; C++);
       if (*C != ':')
 	 continue;
@@ -173,9 +188,10 @@ bool pkgTagSection::Find(const char *Tag,const char *&Start,
       End = Section + Indexes[I+1];
       for (; (isspace(*Start) != 0 || *Start == ':') && Start < End; Start++);
       for (; isspace(End[-1]) != 0 && End > Start; End--);
-      
+
       return true;
    }
+   
    Start = End = 0;
    return false;
 }

+ 3 - 1
apt-pkg/tagfile.h

@@ -1,6 +1,6 @@
 // -*- mode: cpp; mode: fold -*-
 // Description								/*{{{*/
-// $Id: tagfile.h,v 1.11 1998/11/28 03:54:31 jgg Exp $
+// $Id: tagfile.h,v 1.12 1998/12/07 07:26:23 jgg Exp $
 /* ######################################################################
 
    Fast scanner for RFC-822 type header information
@@ -34,6 +34,8 @@ class pkgTagSection
    
    // We have a limit of 256 tags per section.
    unsigned short Indexes[256];
+   unsigned short AlphaIndexes[26 + 26*26];
+   
    unsigned int TagCount;
      
    public:

+ 4 - 0
buildlib/defaults.mak

@@ -69,6 +69,10 @@ ifdef STATICLIBS
 LIBRARY_H += $(BASE)/buildlib/staticlibrary.mak
 endif
 
+ifdef ONLYSTATICLIBS
+LIBRARY_H = $(BASE)/buildlib/staticlibrary.mak
+endif
+
 # Source location control
 # SUBDIRS specifies sub components of the module that
 # may be located in subdrictories of the source dir. 

+ 1 - 1
buildlib/program.mak

@@ -31,7 +31,7 @@ veryclean/$(LOCAL): clean/$(LOCAL)
 # The binary build rule
 $($(LOCAL)-BIN): $($(LOCAL)-OBJS)
 	echo Building program $@
-	$(CXX) $(CXXFLAGS) $(LDFLAGS) $(LFLAGS) $($(LOCAL)-SLIBS) -o $@ $(filter %.o,$^)
+	$(CXX) $(CXXFLAGS) $(LDFLAGS) $(LFLAGS) -o $@ $(filter %.o,$^) $($(LOCAL)-SLIBS)
 
 # Compilation rules
 vpath %.cc $(SUBDIRS)

+ 30 - 5
methods/http.cc

@@ -1,6 +1,6 @@
 // -*- mode: cpp; mode: fold -*-
 // Description								/*{{{*/
-// $Id: http.cc,v 1.9 1998/12/05 04:19:05 jgg Exp $
+// $Id: http.cc,v 1.10 1998/12/07 07:26:27 jgg Exp $
 /* ######################################################################
 
    HTTP Aquire Method - This is the HTTP aquire method for APT.
@@ -51,6 +51,7 @@
 string HttpMethod::FailFile;
 int HttpMethod::FailFd = -1;
 time_t HttpMethod::FailTime = 0;
+unsigned long PipelineDepth = 5;
 
 // CircleBuf::CircleBuf - Circular input buffer				/*{{{*/
 // ---------------------------------------------------------------------
@@ -572,9 +573,9 @@ bool ServerState::HeaderLine(string Line)
 void HttpMethod::SendReq(FetchItem *Itm,CircleBuf &Out)
 {
    URI Uri = Itm->Uri;
-   
+
    // The HTTP server expects a hostname with a trailing :port
-   char Buf[300];
+   char Buf[1000];
    string ProperHost = Uri.Host;
    if (Uri.Port != 0)
    {
@@ -582,6 +583,10 @@ void HttpMethod::SendReq(FetchItem *Itm,CircleBuf &Out)
       ProperHost += Buf;
    }   
       
+   // Just in case.
+   if (Itm->Uri.length() >= sizeof(Buf))
+       abort();
+       
    /* Build the request. We include a keep-alive header only for non-proxy
       requests. This is to tweak old http/1.0 servers that do support keep-alive
       but not HTTP/1.1 automatic keep-alive. Doing this with a proxy server 
@@ -592,8 +597,27 @@ void HttpMethod::SendReq(FetchItem *Itm,CircleBuf &Out)
       sprintf(Buf,"GET %s HTTP/1.1\r\nHost: %s\r\nConnection: keep-alive\r\n",
 	      Uri.Path.c_str(),ProperHost.c_str());
    else
+   {
+      /* Generate a cache control header if necessary. We place a max
+       	 cache age on index files, optionally set a no-cache directive
+       	 and a no-store directive for archives. */
       sprintf(Buf,"GET %s HTTP/1.1\r\nHost: %s\r\n",
 	      Itm->Uri.c_str(),ProperHost.c_str());
+      if (_config->FindB("Acquire::http::No-Cache",false) == true)
+	 strcat(Buf,"Cache-Control: no-cache\r\n");
+      else
+      {
+	 if (Itm->IndexFile == true)
+	    sprintf(Buf+strlen(Buf),"Cache-Control: max-age=%u\r\n",
+		    _config->FindI("Acquire::http::Max-Age",60*60*24));
+	 else
+	 {
+	    if (_config->FindB("Acquire::http::No-Store",false) == true)
+	       strcat(Buf,"Cache-Control: no-store\r\n");
+	 }	 
+      }
+   }
+   
    string Req = Buf;
 
    // Check for a partial file
@@ -619,7 +643,8 @@ void HttpMethod::SendReq(FetchItem *Itm,CircleBuf &Out)
 
    Req += "User-Agent: Debian APT-HTTP/1.2\r\n\r\n";
 //   cerr << Req << endl;
-   
+
+   cerr << Req << endl;
    Out.Read(Req);
 }
 									/*}}}*/
@@ -892,7 +917,7 @@ bool HttpMethod::Fetch(FetchItem *)
    // Queue the requests
    int Depth = -1;
    bool Tail = false;
-   for (FetchItem *I = Queue; I != 0 && Depth < 5; I = I->Next, Depth++)
+   for (FetchItem *I = Queue; I != 0 && Depth < (signed)PipelineDepth; I = I->Next, Depth++)
    {
       // Make sure we stick with the same server
       if (Server->Comp(I->Uri) == false)