Use lazy-deserialization and package cache when searching in package name

This commit is contained in:
Martchus 2022-02-19 00:11:59 +01:00
parent 3d7310af30
commit a7de520549
6 changed files with 39 additions and 8 deletions

2
3rdparty/lmdb-safe vendored

@ -1 +1 @@
Subproject commit b302cdfabe190ad4b1853a6e8b1837886c58dd4a
Subproject commit b87dd49bbaef54d71c3cd25e46db0ff86e73f469

View File

@ -186,8 +186,27 @@ std::vector<PackageSearchResult> Config::findPackages(const std::regex &regex)
{
auto pkgs = std::vector<PackageSearchResult>();
for (auto &db : databases) {
db.allPackages([&](StorageID packageID, const std::shared_ptr<Package> &package) {
if (std::regex_match(package->name, regex)) {
db.allPackagesByName([&](std::string_view packageName, const std::function<PackageSpec(void)> &getPackage) {
if (std::regex_match(packageName.begin(), packageName.end(), regex)) {
auto [packageID, package] = getPackage();
pkgs.emplace_back(db, package, packageID);
}
return false;
});
}
return pkgs;
}
std::vector<PackageSearchResult> Config::findPackages(const std::function<bool(const Database &)> &databasePred, std::string_view term)
{
auto pkgs = std::vector<PackageSearchResult>();
for (auto &db : databases) {
if (!databasePred(db)) {
continue;
}
db.allPackagesByName([&](std::string_view packageName, const std::function<PackageSpec(void)> &getPackage) {
if (packageName.find(term) != std::string_view::npos) {
const auto [packageID, package] = getPackage();
pkgs.emplace_back(db, package, packageID);
}
return false;

View File

@ -147,6 +147,7 @@ struct LIBPKG_EXPORT Config : public Lockable, public ReflectiveRapidJSON::Binar
std::vector<PackageSearchResult> findPackages(const Dependency &dependency, bool reverse = false);
std::vector<PackageSearchResult> findPackagesProvidingLibrary(const std::string &library, bool reverse = false);
std::vector<PackageSearchResult> findPackages(const std::regex &regex);
std::vector<PackageSearchResult> findPackages(const std::function<bool(const Database &)> &databasePred, std::string_view term);
std::vector<PackageSearchResult> findPackages(const Package &package);
std::vector<PackageSearchResult> findPackages(
const std::function<bool(const Database &)> &databasePred, const std::function<bool(const Database &, const Package &)> &packagePred);

View File

@ -104,12 +104,11 @@ void Database::clearPackages()
std::vector<std::shared_ptr<Package>> Database::findPackages(const std::function<bool(const Database &, const Package &)> &pred)
{
// TODO: use cache here
// TODO: avoid std::move()
auto pkgs = std::vector<std::shared_ptr<Package>>();
auto txn = m_storage->packages.getROTransaction();
for (auto i = txn.begin(); i != txn.end(); ++i) {
for (auto i = txn.begin<std::shared_ptr>(); i != txn.end(); ++i) {
if (pred(*this, *i)) {
pkgs.emplace_back(std::make_shared<Package>(std::move(*i)));
pkgs.emplace_back(std::move(i.getPointer()));
}
}
return pkgs;
@ -257,6 +256,17 @@ void Database::allPackages(const PackageVisitor &visitor)
}
}
void LibPkg::Database::allPackagesByName(const PackageVisitorByName &visitor)
{
auto txn = m_storage->packages.getROTransaction();
for (auto i = txn.begin_idx<0, std::shared_ptr>(); i != txn.end(); ++i) {
const auto packageName = i.getKey().get<string_view>();
if (visitor(packageName, [this, &txn, &i]() { return m_storage->packageCache.retrieve(*m_storage, &txn, i.value()); })) {
return;
}
}
}
std::size_t Database::packageCount() const
{
return m_storage->packages.getROTransaction().size();

View File

@ -113,6 +113,7 @@ private:
struct LIBPKG_EXPORT Database : public ReflectiveRapidJSON::JsonSerializable<Database>, public ReflectiveRapidJSON::BinarySerializable<Database> {
using PackageVisitor = std::function<bool(StorageID, const std::shared_ptr<Package> &)>;
using PackageVisitorByName = std::function<bool(std::string_view, const std::function<PackageSpec(void)> &)>;
friend struct PackageUpdater;
@ -134,6 +135,7 @@ struct LIBPKG_EXPORT Database : public ReflectiveRapidJSON::JsonSerializable<Dat
void removePackageDependencies(StorageID packageID, const std::shared_ptr<Package> &package);
void addPackageDependencies(StorageID packageID, const std::shared_ptr<Package> &package);
void allPackages(const PackageVisitor &visitor);
void allPackagesByName(const PackageVisitorByName &visitor);
std::size_t packageCount() const;
void providingPackages(const Dependency &dependency, bool reverse, const PackageVisitor &visitor);
void providingPackages(const std::string &libraryName, bool reverse, const PackageVisitor &visitor);

View File

@ -265,8 +265,7 @@ void getPackages(const Params &params, ResponseHandler &&handler)
}
case Mode::NameContains:
pushPackages(params.setup.config.findPackages(
[&dbs, onlyFromAur](const LibPkg::Database &db) { return (dbs.empty() && !onlyFromAur) || dbs.find(db.name) != dbs.end(); },
[&name](const LibPkg::Database &, const LibPkg::Package &pkg) { return pkg.name.find(name) != std::string::npos; }));
[&dbs, onlyFromAur](const LibPkg::Database &db) { return (dbs.empty() && !onlyFromAur) || dbs.find(db.name) != dbs.end(); }, name));
if (fromAur && !name.empty()) {
neededAurPackages.emplace_back(std::move(name));
}