Fix up provider lookups tremendously

parent 0ba61452
......@@ -79,39 +79,87 @@ Package::Package(std::istream& from_pkginfo) : _done_deps(false), _done_ii(false
}
}
std::set<string>* Package::depends() {
void Package::maybe_load_depends() {
if(!this->_done_deps) {
this->_done_deps = true;
std::istringstream atom_stream(_raw_deps);
this->_dependencies = new std::set<string>({std::istream_iterator<string>(atom_stream), std::istream_iterator<string>()});
}
}
std::set<string>* Package::depends() {
this->maybe_load_depends();
return this->_dependencies;
}
std::set<string>* Package::install_if() {
void Package::maybe_load_install_if() {
if(!this->_done_ii) {
this->_done_ii = true;
std::istringstream atom_stream(_raw_ii);
this->_install_if = new std::set<string>({std::istream_iterator<string>(atom_stream), std::istream_iterator<string>()});
}
}
std::set<string>* Package::install_if() {
this->maybe_load_install_if();
return this->_install_if;
}
std::set<string>* Package::provides() {
void Package::maybe_load_provides() {
if(!this->_done_prov) {
this->_done_prov = true;
std::istringstream atom_stream(_raw_prov);
this->_provides = new std::set<string>({std::istream_iterator<string>(atom_stream), std::istream_iterator<string>()});
std::transform(this->_provides->cbegin(), this->_provides->cend(), std::inserter(this->_named_provides, this->_named_provides.end()), [](const string& elem) {
string::size_type equals = elem.find("=");
if(equals != string::npos) return string(elem.substr(0, equals));
return string(elem);
});
}
}
std::set<string>* Package::provides() {
this->maybe_load_provides();
return this->_provides;
}
std::set<string>* Package::replaces() {
bool Package::can_provide(const string& name) {
if(this->_name == name) return true;
this->maybe_load_provides();
for (auto const &elem : this->_named_provides) { if(elem == name) return true; }
return false;
}
bool Package::can_provide(const string& name, const PackageVersion& version) {
if(this->_name == name) return true;
this->maybe_load_provides();
for (auto const &elem : *this->_provides) {
string::size_type equals;
equals = elem.find("=");
// Without a specified provider version, this provides any version
if(equals == string::npos && elem == name) return true;
if(elem.substr(0, equals) == name && PackageVersion(elem.substr(equals)) == version)
return true;
}
return false;
}
bool Package::can_provide(const string& name, const string& version) {
return this->can_provide(name, PackageVersion(version));
}
void Package::maybe_load_replaces() {
if(!this->_done_replace) {
this->_done_replace = true;
std::istringstream atom_stream(_raw_replace);
this->_replaces = new std::set<string>({std::istream_iterator<string>(atom_stream), std::istream_iterator<string>()});
}
}
std::set<string>* Package::replaces() {
this->maybe_load_replaces();
return this->_replaces;
}
......
......@@ -12,7 +12,7 @@ namespace Parcel {
class PackageVersion {
public:
PackageVersion(std::string from) {
PackageVersion(const string& from) {
string::size_type revplace = from.rfind("-r");
if(revplace == string::npos) {
_version = string(from);
......@@ -40,10 +40,18 @@ public:
}
friend bool operator<(const PackageVersion &left, const PackageVersion &right) {
assert("NYI");
assert(false); // NYI
return false;
}
friend bool operator>(const PackageVersion &left, const PackageVersion &right) { return right < left; }
bool compare(const PackageVersion &other, bool fuzzy = false) {
if(!fuzzy) return (this->_version == other._version && this->_revision == other._revision);
assert(false); // NYI
return false;
}
bool operator==(const PackageVersion& other) { return this->compare(other); }
private:
string _version;
unsigned long _revision;
......@@ -60,6 +68,9 @@ public:
const string arch() { return _arch; }
std::set<string>* depends();
std::set<string>* install_if();
bool can_provide(const string& name);
bool can_provide(const string& name, const string& version);
bool can_provide(const string& name, const PackageVersion& version);
std::set<string>* provides();
std::set<string>* replaces();
const string maintainer() { return _maintainer; }
......@@ -84,6 +95,7 @@ private:
string _raw_prov;
bool _done_prov;
std::set<string>* _provides;
std::set<string> _named_provides;
string _raw_replace;
bool _done_replace;
std::set<string>* _replaces;
......@@ -93,6 +105,10 @@ private:
string _commit_id;
string _origin;
void maybe_load_depends();
void maybe_load_install_if();
void maybe_load_provides();
void maybe_load_replaces();
Package(std::istream& from_pkginfo);
friend class Repository;
};
......
......@@ -39,18 +39,14 @@ Repository::~Repository() {
for(auto pkg : _packages) { delete pkg; }
}
inline vector<Package*>::const_iterator find_package_by_name(vector<Package*> packages, string name) {
return find_if(packages.cbegin(), packages.cend(),
bool Repository::has_package(const string& name) {
return std::find_if(this->_packages.cbegin(), this->_packages.cend(),
[name](Package* elem) {
return elem->pkgname() == name;
});
}
bool Repository::has_package(string name) {
return find_package_by_name(this->_packages, name) != this->_packages.cend();
}) != this->_packages.cend();
}
Package* Repository::package(string name) {
Package* Repository::package(const string& name) {
vector<Package*> maybe_pkgs;
std::copy_if(this->_packages.cbegin(), this->_packages.cend(), std::back_inserter(maybe_pkgs),
......@@ -65,23 +61,13 @@ Package* Repository::package(string name) {
});
}
vector<Package*> Repository::providers(string name) {
vector<Package*> Repository::providers(const string& name) {
vector<Package*> provider_list;
std::copy_if(this->_packages.cbegin(), this->_packages.cend(), std::back_inserter(provider_list),
[name](Package* elem) {
// if the package name exactly matches, this is automatically a provider
if(elem->pkgname() == name) return true;
// no version specified, so find any version
std::set<string>* providers = elem->provides();
return std::any_of(providers->begin(), providers->end(), [name](string elem){
string::size_type equals;
if(elem == name) return true;
equals = elem.find("=");
if(equals != string::npos) return elem.substr(0, equals) == name;
return false;
});
return elem->can_provide(name);
});
return provider_list;
......
......@@ -18,9 +18,9 @@ public:
std::vector<Package*> packages() { return _packages; }
/*! True if at least one Package is present in this repository with
* the specified name */
bool has_package(string name);
bool has_package(const string& name);
/*! The newest version of the package specified by `name` */
Package* package(string name);
Package* package(const string& name);
/*! Number of packages in this repository */
unsigned long package_count() { return _packages.size(); }
/*! Names of every origin package in this repository */
......@@ -28,7 +28,7 @@ public:
/*! Number of origin packages in this repository */
unsigned long origin_count() { return _origins.size(); }
/*! All packages that provide `name`. */
std::vector<Package*> providers(string name);
std::vector<Package*> providers(const string& name);
private:
std::vector<Package*> _packages;
std::unordered_set<string> _origins;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment