From: Jay Freeman (saurik) Date: Wed, 24 Feb 2010 10:01:00 +0000 (+0000) Subject: Slightly decrease the memory used by the Name tables. X-Git-Url: https://git.saurik.com/apt-legacy.git/commitdiff_plain/b6d30aa2a834513b9bd1317d71f930d172b281da Slightly decrease the memory used by the Name tables. A tornado.diff A unique.diff D vindication.diff git-svn-id: http://svn.telesphoreo.org/trunk@704 514c082c-b64e-11dc-b46d-3d985efe055d --- diff --git a/apt-pkg/contrib/strutl.h b/apt-pkg/contrib/strutl.h index addc1f4..28a7fff 100644 --- a/apt-pkg/contrib/strutl.h +++ b/apt-pkg/contrib/strutl.h @@ -77,6 +77,7 @@ inline int name(const string& A,const string& B) {return func(A.c_str(),A.c_str( inline int name(const string& A,const char *B,const char *BEnd) {return func(A.c_str(),A.c_str()+A.length(),B,BEnd);}; #define APT_MKSTRCMP2(name,func) \ +inline int name(const srkString &A,const char *B) {return func(A.Start,A.Start+A.Size,B,B+strlen(B));}; \ inline int name(const char *A,const char *AEnd,const char *B) {return func(A,AEnd,B,B+strlen(B));}; \ inline int name(const string& A,const char *B) {return func(A.begin(),A.end(),B,B+strlen(B));}; \ inline int name(const string& A,const string& B) {return func(A.begin(),A.end(),B.begin(),B.end());}; \ diff --git a/apt-pkg/contrib/strutl.h.orig b/apt-pkg/contrib/strutl.h.orig new file mode 100644 index 0000000..2b2e147 --- /dev/null +++ b/apt-pkg/contrib/strutl.h.orig @@ -0,0 +1,147 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: strutl.h,v 1.22 2003/02/02 22:20:27 jgg Exp $ +/* ###################################################################### + + String Util - These are some useful string functions + + _strstrip is a function to remove whitespace from the front and end + of a string. + + This source is placed in the Public Domain, do with it what you will + It was originally written by Jason Gunthorpe + + ##################################################################### */ + /*}}}*/ +#ifndef STRUTL_H +#define STRUTL_H + + + +#include +#include +#include +#include +#include +#include + +using std::string; +using std::vector; +using std::ostream; + +#ifdef __GNUG__ +// Methods have a hidden this parameter that is visible to this attribute +#define APT_FORMAT2 __attribute__ ((format (printf, 2, 3))) +#define APT_FORMAT3 __attribute__ ((format (printf, 3, 4))) +#else +#define APT_FORMAT2 +#define APT_FORMAT3 +#endif + +bool UTF8ToCodeset(const char *codeset, const string &orig, string *dest); +char *_strstrip(char *String); +char *_strtabexpand(char *String,size_t Len); +bool ParseQuoteWord(const char *&String,string &Res); +bool ParseCWord(const char *&String,string &Res); +string QuoteString(const string &Str,const char *Bad); +string DeQuoteString(const string &Str); +string SizeToStr(double Bytes); +string TimeToStr(unsigned long Sec); +string Base64Encode(const string &Str); +string OutputInDepth(const unsigned long Depth, const char* Separator=" "); +string URItoFileName(const string &URI); +string TimeRFC1123(time_t Date); +bool StrToTime(const string &Val,time_t &Result); +string LookupTag(const string &Message,const char *Tag,const char *Default = 0); +int StringToBool(const string &Text,int Default = -1); +bool ReadMessages(int Fd, vector &List); +bool StrToNum(const char *Str,unsigned long &Res,unsigned Len,unsigned Base = 0); +bool Hex2Num(const string &Str,unsigned char *Num,unsigned int Length); +bool TokSplitString(char Tok,char *Input,char **List, + unsigned long ListMax); +void ioprintf(ostream &out,const char *format,...) APT_FORMAT2; +void strprintf(string &out,const char *format,...) APT_FORMAT2; +char *safe_snprintf(char *Buffer,char *End,const char *Format,...) APT_FORMAT3; +bool CheckDomainList(const string &Host, const string &List); +int tolower_ascii(int c); + +#define APT_MKSTRCMP(name,func) \ +inline int name(const char *A,const char *B) {return func(A,A+strlen(A),B,B+strlen(B));}; \ +inline int name(const char *A,const char *AEnd,const char *B) {return func(A,AEnd,B,B+strlen(B));}; \ +inline int name(const string& A,const char *B) {return func(A.c_str(),A.c_str()+A.length(),B,B+strlen(B));}; \ +inline int name(const string& A,const string& B) {return func(A.c_str(),A.c_str()+A.length(),B.c_str(),B.c_str()+B.length());}; \ +inline int name(const string& A,const char *B,const char *BEnd) {return func(A.c_str(),A.c_str()+A.length(),B,BEnd);}; + +#define APT_MKSTRCMP2(name,func) \ +inline int name(const char *A,const char *AEnd,const char *B) {return func(A,AEnd,B,B+strlen(B));}; \ +inline int name(const string& A,const char *B) {return func(A.begin(),A.end(),B,B+strlen(B));}; \ +inline int name(const string& A,const string& B) {return func(A.begin(),A.end(),B.begin(),B.end());}; \ +inline int name(const string& A,const char *B,const char *BEnd) {return func(A.begin(),A.end(),B,BEnd);}; + +int stringcmp(const char *A,const char *AEnd,const char *B,const char *BEnd); +int stringcasecmp(const char *A,const char *AEnd,const char *B,const char *BEnd); + +/* We assume that GCC 3 indicates that libstdc++3 is in use too. In that + case the definition of string::const_iterator is not the same as + const char * and we need these extra functions */ +#if __GNUC__ >= 3 +int stringcmp(string::const_iterator A,string::const_iterator AEnd, + const char *B,const char *BEnd); +int stringcmp(string::const_iterator A,string::const_iterator AEnd, + string::const_iterator B,string::const_iterator BEnd); +int stringcasecmp(string::const_iterator A,string::const_iterator AEnd, + const char *B,const char *BEnd); +int stringcasecmp(string::const_iterator A,string::const_iterator AEnd, + string::const_iterator B,string::const_iterator BEnd); + +inline int stringcmp(string::const_iterator A,string::const_iterator Aend,const char *B) {return stringcmp(A,Aend,B,B+strlen(B));}; +inline int stringcasecmp(string::const_iterator A,string::const_iterator Aend,const char *B) {return stringcasecmp(A,Aend,B,B+strlen(B));}; +#endif + +APT_MKSTRCMP2(stringcmp,stringcmp); +APT_MKSTRCMP2(stringcasecmp,stringcasecmp); + +inline const char *DeNull(const char *s) {return (s == 0?"(null)":s);}; + +class URI +{ + void CopyFrom(const string &From); + + public: + + string Access; + string User; + string Password; + string Host; + string Path; + unsigned int Port; + + operator string(); + inline void operator =(const string &From) {CopyFrom(From);}; + inline bool empty() {return Access.empty();}; + static string SiteOnly(const string &URI); + + URI(string Path) {CopyFrom(Path);}; + URI() : Port(0) {}; +}; + +struct SubstVar +{ + const char *Subst; + const string *Contents; +}; +string SubstVar(string Str,const struct SubstVar *Vars); +string SubstVar(const string &Str,const string &Subst,const string &Contents); + +struct RxChoiceList +{ + void *UserData; + const char *Str; + bool Hit; +}; +unsigned long RegexChoice(RxChoiceList *Rxs,const char **ListBegin, + const char **ListEnd); + +#undef APT_FORMAT2 + +#endif diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index 964e4a4..c55fd42 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -45,7 +45,7 @@ unsigned long debListParser::FindTagWrite(const char *Tag) const char *Stop; if (Section.Find(Tag,Start,Stop) == false) return 0; - return WriteString(Start,Stop - Start); + return WriteString(srkString(Start,Stop - Start)); } /*}}}*/ // ListParser::UniqFindTagWrite - Find the tag and write a unq string /*{{{*/ diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc index 48a7976..7e67733 100644 --- a/apt-pkg/pkgcachegen.cc +++ b/apt-pkg/pkgcachegen.cc @@ -680,21 +680,38 @@ bool pkgCacheGenerator::SelectFile(const string &File,const string &Site, unsigned long pkgCacheGenerator::WriteUniqString(const char *S, unsigned int Size) { + return WriteString(srkString(S, Size), srkSeriouslyUnique); +} + +unsigned long pkgCacheGenerator::WriteString(const srkString &S, + enum srkLevel level) +{ + if (level == srkRunOfTheMillNormal) + return Map.WriteString(S.Start,S.Size); + /* We use a very small transient hash table here, this speeds up generation by a fair amount on slower machines */ - pkgCache::StringItem *&Bucket = UniqHash[(S[0]*5 + S[1]) % _count(UniqHash)]; + pkgCache::StringItem *&Bucket(level == srkReasonablySpecial ? SpecHash[(S[0]*5 + S[1]) % _count(SpecHash)] : UniqHash[(S[0]*5 + S[1]) % _count(UniqHash)]); if (Bucket != 0 && - stringcmp(S,S+Size,Cache.StrP + Bucket->String) == 0) + stringcmp(S,Cache.StrP + Bucket->String) == 0) return Bucket->String; + pkgCache::StringItem *I; + map_ptrloc *Last; + + if (level != srkSeriouslyUnique) { + I = NULL; + Last = NULL; + } else { + // Search for an insertion point - pkgCache::StringItem *I = Cache.StringItemP + Cache.HeaderP->StringList; + I = Cache.StringItemP + Cache.HeaderP->StringList; int Res = 1; - map_ptrloc *Last = &Cache.HeaderP->StringList; + Last = &Cache.HeaderP->StringList; for (; I != Cache.StringItemP; Last = &I->NextItem, I = Cache.StringItemP + I->NextItem) { - Res = stringcmp(S,S+Size,Cache.StrP + I->String); + Res = stringcmp(S,Cache.StrP + I->String); if (Res >= 0) break; } @@ -705,6 +722,8 @@ unsigned long pkgCacheGenerator::WriteUniqString(const char *S, Bucket = I; return I->String; } + + } // Get a structure unsigned long Item = Map.Allocate(sizeof(pkgCache::StringItem)); @@ -714,8 +733,9 @@ unsigned long pkgCacheGenerator::WriteUniqString(const char *S, // Fill in the structure pkgCache::StringItem *ItemP = Cache.StringItemP + Item; ItemP->NextItem = I - Cache.StringItemP; - *Last = Item; - ItemP->String = Map.WriteString(S,Size); + if (Last != NULL) + *Last = Item; + ItemP->String = Map.WriteString(S.Start,S.Size); if (ItemP->String == 0) return 0; diff --git a/apt-pkg/pkgcachegen.h b/apt-pkg/pkgcachegen.h index 306b117..7c523c7 100644 --- a/apt-pkg/pkgcachegen.h +++ b/apt-pkg/pkgcachegen.h @@ -32,13 +32,16 @@ class pkgCacheGenerator /*{{{*/ { private: - pkgCache::StringItem *UniqHash[26]; + pkgCache::StringItem *UniqHash[24]; + pkgCache::StringItem *SpecHash[2]; public: class ListParser; friend class ListParser; + enum srkLevel { srkRunOfTheMillNormal, srkReasonablySpecial, srkSeriouslyUnique }; + protected: DynamicMMap ⤅ @@ -63,6 +66,7 @@ class pkgCacheGenerator /*{{{*/ unsigned long WriteUniqString(const char *S,unsigned int Size); inline unsigned long WriteUniqString(const string &S) {return WriteUniqString(S.c_str(),S.length());}; + unsigned long WriteString(const srkString &S, enum srkLevel level); void DropProgress() {Progress = 0;}; bool SelectFile(const string &File,const string &Site,pkgIndexFile const &Index, @@ -98,7 +102,7 @@ class pkgCacheGenerator::ListParser inline unsigned long WriteUniqString(const char *S,unsigned int Size) {return Owner->WriteUniqString(S,Size);}; inline unsigned long WriteString(const string &S) {return Owner->Map.WriteString(S);}; inline unsigned long WriteString(const char *S,unsigned int Size) {return Owner->Map.WriteString(S,Size);}; - inline unsigned long WriteString(const srkString &S) {return Owner->Map.WriteString(S.Start,S.Size);}; + inline unsigned long WriteString(const srkString &S) {return Owner->WriteString(S, srkReasonablySpecial);}; bool NewDepends(pkgCache::VerIterator Ver,const string &Package, const string &Version,unsigned int Op, unsigned int Type); diff --git a/apt-pkg/srkstring.h b/apt-pkg/srkstring.h index a8fa123..7e90ed2 100644 --- a/apt-pkg/srkstring.h +++ b/apt-pkg/srkstring.h @@ -51,11 +51,6 @@ class srkString operator std::string() { std::string Str; Str.assign(Start, Size); return Str; } }; -int stringcasecmp(const char *lhsb, const char *lhse, const char *rhs); -inline int stringcasecmp(const srkString &lhs, const char *rhs) { - return stringcasecmp(lhs.Start, lhs.Start + lhs.Size, rhs); -} - int stringcmp(const std::string &lhs, const char *rhsb, const char *rhse); inline bool operator ==(const std::string &lhs, const srkString &rhs) { return stringcmp(lhs, rhs.begin(), rhs.end()) == 0;