Author: jgg
Date: 1998-12-07 07:26:19 GMT
Optimizations
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
// -*- 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
/* ######################################################################
Package Cache - Accessor code for the cache
Package *Pkg = PkgP + HeaderP->HashTable[Hash(Name)];
for (; Pkg != PkgP; Pkg = PkgP + Pkg->NextPackage)
{
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);
return PkgIterator(*this,Pkg);
}
return PkgIterator(*this,0);
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
// -*- 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
/* ######################################################################
Cache - Structure definitions for the cache file
DynamicMMap::Pool Pools[7];
// Rapid package name lookup
DynamicMMap::Pool Pools[7];
// Rapid package name lookup
- __apt_ptrloc HashTable[512];
+ __apt_ptrloc HashTable[2048];
bool CheckSizes(Header &Against) const;
Header();
bool CheckSizes(Header &Against) const;
Header();
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
// -*- 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.
/* ######################################################################
Package Cache Generator - Generator for the cache structure.
if ((Dep->Version = WriteString(Version)) == 0)
return false;
}
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 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;
+
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
// -*- 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
/* ######################################################################
Fast scanner for RFC-822 type header information
// TagSection::Scan - Scan for the end of the header information /*{{{*/
// ---------------------------------------------------------------------
/* This looks for the first double new line in the data stream. It also
// 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;
bool pkgTagSection::Scan(const char *Start,unsigned long MaxLength)
{
const char *End = Start + MaxLength;
Stop = Section = Start;
+ memset(AlphaIndexes,0,sizeof(AlphaIndexes));
- 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)
+ 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;
}
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]);
- }
const char *&End)
{
unsigned int Length = strlen(Tag);
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
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;
for (; isspace(*C) != 0; C++);
if (*C != ':')
continue;
End = Section + Indexes[I+1];
for (; (isspace(*Start) != 0 || *Start == ':') && Start < End; Start++);
for (; isspace(End[-1]) != 0 && End > Start; End--);
End = Section + Indexes[I+1];
for (; (isspace(*Start) != 0 || *Start == ':') && Start < End; Start++);
for (; isspace(End[-1]) != 0 && End > Start; End--);
Start = End = 0;
return false;
}
Start = End = 0;
return false;
}
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
// -*- 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
/* ######################################################################
Fast scanner for RFC-822 type header information
// We have a limit of 256 tags per section.
unsigned short Indexes[256];
// We have a limit of 256 tags per section.
unsigned short Indexes[256];
+ unsigned short AlphaIndexes[26 + 26*26];
+
unsigned int TagCount;
public:
unsigned int TagCount;
public:
LIBRARY_H += $(BASE)/buildlib/staticlibrary.mak
endif
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.
# Source location control
# SUBDIRS specifies sub components of the module that
# may be located in subdrictories of the source dir.
# The binary build rule
$($(LOCAL)-BIN): $($(LOCAL)-OBJS)
echo Building program $@
# 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)
# Compilation rules
vpath %.cc $(SUBDIRS)
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
// -*- 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.
/* ######################################################################
HTTP Aquire Method - This is the HTTP aquire method for APT.
string HttpMethod::FailFile;
int HttpMethod::FailFd = -1;
time_t HttpMethod::FailTime = 0;
string HttpMethod::FailFile;
int HttpMethod::FailFd = -1;
time_t HttpMethod::FailTime = 0;
+unsigned long PipelineDepth = 5;
// CircleBuf::CircleBuf - Circular input buffer /*{{{*/
// ---------------------------------------------------------------------
// CircleBuf::CircleBuf - Circular input buffer /*{{{*/
// ---------------------------------------------------------------------
void HttpMethod::SendReq(FetchItem *Itm,CircleBuf &Out)
{
URI Uri = Itm->Uri;
void HttpMethod::SendReq(FetchItem *Itm,CircleBuf &Out)
{
URI Uri = Itm->Uri;
// The HTTP server expects a hostname with a trailing :port
// The HTTP server expects a hostname with a trailing :port
string ProperHost = Uri.Host;
if (Uri.Port != 0)
{
string ProperHost = Uri.Host;
if (Uri.Port != 0)
{
+ // 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
/* 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
sprintf(Buf,"GET %s HTTP/1.1\r\nHost: %s\r\nConnection: keep-alive\r\n",
Uri.Path.c_str(),ProperHost.c_str());
else
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());
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
string Req = Buf;
// Check for a partial file
Req += "User-Agent: Debian APT-HTTP/1.2\r\n\r\n";
// cerr << Req << endl;
Req += "User-Agent: Debian APT-HTTP/1.2\r\n\r\n";
// cerr << Req << endl;
// Queue the requests
int Depth = -1;
bool Tail = false;
// 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)
{
// Make sure we stick with the same server
if (Server->Comp(I->Uri) == false)