summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJay Freeman (saurik) <saurik@saurik.com>2009-04-20 09:34:48 +0000
committerJay Freeman (saurik) <saurik@saurik.com>2010-09-30 07:13:13 +0000
commit68d927e20c9a9bf2e6dcc2f175fcb2f8fdc1a0d7 (patch)
treec6fbe0ded33f396830086b5de036b9a89da69d32
parent220fa2b077e4e55b36697b39a7a1cf3f380faa38 (diff)
Drastic performance improvements.
-rw-r--r--Cydia.mm231
1 files changed, 123 insertions, 108 deletions
diff --git a/Cydia.mm b/Cydia.mm
index ff3d34c..266415a 100644
--- a/Cydia.mm
+++ b/Cydia.mm
@@ -226,12 +226,18 @@ class _H {
Clear_();
}
+ _finline operator Type_ *() const {
+ return value_;
+ }
+
_finline This_ &operator =(Type_ *value) {
if (value_ != value) {
- Clear_();
+ Type_ *old(value_);
value_ = value;
Retain_();
- } return this;
+ if (old != nil)
+ [old release];
+ } return *this;
}
};
/* }}} */
@@ -399,7 +405,7 @@ extern NSString * const kCAFilterNearest;
#define ForRelease 0
#define TraceLogging (1 && !ForRelease)
#define HistogramInsertionSort (0 && !ForRelease)
-#define ProfileTimes (0 && !ForRelease)
+#define ProfileTimes (1 && !ForRelease)
#define ForSaurik (0 && !ForRelease)
#define LogBrowser (0 && !ForRelease)
#define TrackResize (0 && !ForRelease)
@@ -1139,13 +1145,6 @@ NSString *StripVersion(const char *version) {
return [NSString stringWithUTF8String:version];
}
-NSString *StripVersion(NSString *version) {
- NSRange colon = [version rangeOfString:@":"];
- if (colon.location != NSNotFound)
- version = [version substringFromIndex:(colon.location + 1)];
- return version;
-}
-
NSString *LocalizeSection(NSString *section) {
static Pcre title_r("^(.*?) \\((.*)\\)$");
if (title_r(section)) {
@@ -1347,6 +1346,8 @@ class Progress :
/* }}} */
/* Database Interface {{{ */
+typedef std::map< unsigned long, _H<Source> > SourceMap;
+
@interface Database : NSObject {
NSZone *zone_;
apr_pool_t *pool_;
@@ -1362,7 +1363,7 @@ class Progress :
SPtr<pkgPackageManager> manager_;
pkgSourceList *list_;
- NSMutableDictionary *sources_;
+ SourceMap sources_;
NSMutableArray *packages_;
_transient NSObject<ConfigurationDelegate, ProgressDelegate> *delegate_;
@@ -1657,6 +1658,7 @@ class Progress :
/* Package Class {{{ */
@interface Package : NSObject {
unsigned era_;
+ apr_pool_t *pool_;
pkgCache::VerIterator version_;
pkgCache::PkgIterator iterator_;
@@ -1665,6 +1667,7 @@ class Progress :
Source *source_;
bool cached_;
+ bool parsed_;
CYString section_;
NSString *section$_;
@@ -1703,6 +1706,7 @@ class Progress :
+ (Package *) packageWithIterator:(pkgCache::PkgIterator)iterator withZone:(NSZone *)zone inPool:(apr_pool_t *)pool database:(Database *)database;
- (pkgCache::PkgIterator) iterator;
+- (void) parse;
- (NSString *) section;
- (NSString *) simpleSection;
@@ -1959,11 +1963,75 @@ struct PackageNameOrdering :
return ![[self _attributeKeys] containsObject:[NSString stringWithUTF8String:name]] && [super isKeyExcludedFromWebScript:name];
}
+- (void) parse {
+ if (parsed_)
+ return;
+ parsed_ = true;
+ if (file_.end())
+ return;
+
+ _profile(Package$parse)
+ pkgRecords::Parser *parser;
+
+ _profile(Package$parse$Lookup)
+ parser = &[database_ records]->Lookup(file_);
+ _end
+
+ CYString website;
+
+ _profile(Package$parse$Find)
+ struct {
+ const char *name_;
+ CYString *value_;
+ } names[] = {
+ {"icon", &icon_},
+ {"depiction", &depiction_},
+ {"homepage", &homepage_},
+ {"website", &website},
+ {"support", &support_},
+ {"sponsor", &sponsor_},
+ {"author", &author_},
+ };
+
+ for (size_t i(0); i != sizeof(names) / sizeof(names[0]); ++i) {
+ const char *start, *end;
+
+ if (parser->Find(names[i].name_, start, end)) {
+ CYString &value(*names[i].value_);
+ _profile(Package$parse$Value)
+ value.set(pool_, start, end - start);
+ _end
+ }
+ }
+ _end
+
+ _profile(Package$parse$Tagline)
+ const char *start, *end;
+ if (parser->Find("Description", start, end)) {
+ const char *stop(reinterpret_cast<const char *>(memchr(start, '\n', end - start)));
+ if (stop == NULL)
+ stop = end;
+ while (stop != start && stop[-1] == '\r')
+ --stop;
+ tagline_.set(pool_, start, stop - start);
+ }
+ _end
+
+ _profile(Package$parse$Retain)
+ if (!homepage_.empty())
+ homepage_ = website;
+ if (homepage_ == depiction_)
+ homepage_.clear();
+ _end
+ _end
+}
+
- (Package *) initWithVersion:(pkgCache::VerIterator)version withZone:(NSZone *)zone inPool:(apr_pool_t *)pool database:(Database *)database {
if ((self = [super init]) != nil) {
_profile(Package$initWithVersion)
@synchronized (database) {
era_ = [database era];
+ pool_ = pool;
version_ = version;
iterator_ = version.ParentPkg();
@@ -1973,78 +2041,34 @@ struct PackageNameOrdering :
latest_ = [StripVersion(version_.VerStr()) retain];
_end
- pkgCache::VerIterator current(iterator_.CurrentVer());
- if (!current.end())
- installed_ = [StripVersion(current.VerStr()) retain];
+ pkgCache::VerIterator current;
+ _profile(Package$initWithVersion$Versions)
+ current = iterator_.CurrentVer();
+ if (!current.end())
+ installed_ = [StripVersion(current.VerStr()) retain];
- if (!version_.end())
- file_ = version_.FileList();
- else {
- pkgCache &cache([database_ cache]);
- file_ = pkgCache::VerFileIterator(cache, cache.VerFileP);
- }
+ if (!version_.end())
+ file_ = version_.FileList();
+ else {
+ pkgCache &cache([database_ cache]);
+ file_ = pkgCache::VerFileIterator(cache, cache.VerFileP);
+ }
+ _end
_profile(Package$initWithVersion$Name)
- id_.set(pool, iterator_.Name());
+ id_.set(pool_, iterator_.Name());
_end
- if (!file_.end())
- source_ = [database_ getSource:file_.File()];
- if (source_ != nil)
- [source_ retain];
- cached_ = true;
-
- _profile(Package$initWithVersion$Parse)
- pkgRecords::Parser *parser;
-
- _profile(Package$initWithVersion$Parse$Lookup)
- parser = &[database_ records]->Lookup(file_);
- _end
-
- CYString website;
- CYString tag;
-
- _profile(Package$initWithVersion$Parse$Find)
- struct {
- const char *name_;
- CYString *value_;
- } names[] = {
- {"name", &name_},
- {"icon", &icon_},
- {"depiction", &depiction_},
- {"homepage", &homepage_},
- {"website", &website},
- {"support", &support_},
- {"sponsor", &sponsor_},
- {"author", &author_},
- {"tag", &tag},
- };
-
- for (size_t i(0); i != sizeof(names) / sizeof(names[0]); ++i) {
- const char *start, *end;
-
- if (parser->Find(names[i].name_, start, end)) {
- CYString &value(*names[i].value_);
- _profile(Package$initWithVersion$Parse$Value)
- value.set(pool, start, end - start);
- _end
- }
- }
- _end
-
- _profile(Package$initWithVersion$Parse$Tagline)
- tagline_.set(pool, parser->ShortDesc());
- _end
-
- _profile(Package$initWithVersion$Parse$Retain)
- if (!homepage_.empty())
- homepage_ = website;
- if (homepage_ == depiction_)
- homepage_.clear();
- if (!tag.empty())
- tags_ = [[tag componentsSeparatedByString:@", "] retain];
- _end
+ if (!file_.end()) {
+ _profile(Package$initWithVersion$Source)
+ source_ = [database_ getSource:file_.File()];
+ if (source_ != nil)
+ [source_ retain];
+ cached_ = true;
_end
+ }
+
+ /* XXX: get the damned Name */
_profile(Package$initWithVersion$Tags)
if (tags_ != nil)
@@ -2105,7 +2129,7 @@ struct PackageNameOrdering :
_end
_profile(Package$initWithVersion$Section)
- section_.set(pool, iterator_.Section());
+ section_.set(pool_, iterator_.Section());
_end
essential_ = ((iterator_->Flags & pkgCache::Flag::Essential) == 0 ? NO : YES) || [self hasTag:@"cydia::essential"];
@@ -2930,7 +2954,6 @@ static NSArray *Finishes_;
zone_ = NSCreateZone(1024 * 1024, 256 * 1024, NO);
apr_pool_create(&pool_, NULL);
- sources_ = [[NSMutableDictionary dictionaryWithCapacity:16] retain];
packages_ = [[NSMutableArray alloc] init];
int fds[2];
@@ -3003,7 +3026,10 @@ static NSArray *Finishes_;
}
- (NSArray *) sources {
- return [sources_ allValues];
+ NSMutableArray *sources([NSMutableArray arrayWithCapacity:sources_.size()]);
+ for (SourceMap::const_iterator i(sources_.begin()); i != sources_.end(); ++i)
+ [sources addObject:i->second];
+ return sources;
}
- (NSArray *) issues {
@@ -3144,23 +3170,19 @@ static NSArray *Finishes_;
}
_trace();
- {
- std::string lists(_config->FindDir("Dir::State::lists"));
-
- [sources_ removeAllObjects];
- for (pkgSourceList::const_iterator source = list_->begin(); source != list_->end(); ++source) {
- std::vector<pkgIndexFile *> *indices = (*source)->GetIndexFiles();
- for (std::vector<pkgIndexFile *>::const_iterator index = indices->begin(); index != indices->end(); ++index)
- if (debPackagesIndex *packages = dynamic_cast<debPackagesIndex *>(*index))
- [sources_
- setObject:[[[Source alloc] initWithMetaIndex:*source] autorelease]
- forKey:[NSString stringWithFormat:@"%s%s",
- lists.c_str(),
- URItoFileName(packages->IndexURI("Packages")).c_str()
- ]
- ];
- }
+
+ sources_.clear();
+ for (pkgSourceList::const_iterator source = list_->begin(); source != list_->end(); ++source) {
+ std::vector<pkgIndexFile *> *indices = (*source)->GetIndexFiles();
+ for (std::vector<pkgIndexFile *>::const_iterator index = indices->begin(); index != indices->end(); ++index)
+ // XXX: this could be more intelligent
+ if (dynamic_cast<debPackagesIndex *>(*index) != NULL) {
+ pkgCache::PkgFileIterator cached((*index)->FindInCache(cache_));
+ if (!cached.end())
+ sources_[cached->ID] = [[[Source alloc] initWithMetaIndex:*source] autorelease];
+ }
}
+
_trace();
{
@@ -3368,10 +3390,7 @@ static NSArray *Finishes_;
}
- (Source *) getSource:(pkgCache::PkgFileIterator)file {
- if (const char *name = file.FileName())
- if (Source *source = [sources_ objectForKey:[NSString stringWithUTF8String:name]])
- return source;
- return nil;
+ return sources_[file->ID];
}
@end
@@ -4323,6 +4342,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
- (void) setPackage:(Package *)package {
[self clearPackage];
+ [package parse];
Source *source = [package source];
@@ -4453,14 +4473,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
}
+ (int) heightForPackage:(Package *)package {
- NSString *tagline([package shortDescription]);
- int height = tagline == nil || [tagline length] == 0 ? -17 : 0;
-#ifdef USE_BADGES
- if ([package hasMode] || [package half])
- return height + 96;
- else
-#endif
- return height + 73;
+ return 73;
}
@end
@@ -4845,6 +4858,8 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
[buttons_ removeAllObjects];
if (package != nil) {
+ [package parse];
+
package_ = [package retain];
name_ = [[package id] retain];
commercial_ = [package isCommercial];