Update/remove packages from database in a whole transaction
This commit is contained in:
parent
84ef92aaa2
commit
407e3159e0
|
@ -177,39 +177,36 @@ static void removeLibDependency(LibraryDependencyStorage::RWTransaction &txn, St
|
|||
}
|
||||
}
|
||||
|
||||
void Database::removePackageDependencies(StorageID packageID, const std::shared_ptr<Package> &package)
|
||||
static void removePackageDependencies(DatabaseStorage &storage, const std::shared_ptr<LMDBSafe::MDBRWTransaction> &txnHandle, StorageID packageID,
|
||||
const std::shared_ptr<Package> &package)
|
||||
{
|
||||
{
|
||||
auto txn = m_storage->providedDeps.getRWTransaction();
|
||||
auto txn = storage.providedDeps.getRWTransaction(txnHandle);
|
||||
removeDependency(txn, packageID, package->name);
|
||||
for (const auto &dep : package->provides) {
|
||||
removeDependency(txn, packageID, dep.name);
|
||||
}
|
||||
txn.commit();
|
||||
}
|
||||
{
|
||||
auto txn = m_storage->requiredDeps.getRWTransaction();
|
||||
auto txn = storage.requiredDeps.getRWTransaction(txnHandle);
|
||||
for (const auto &dep : package->dependencies) {
|
||||
removeDependency(txn, packageID, dep.name);
|
||||
}
|
||||
for (const auto &dep : package->optionalDependencies) {
|
||||
removeDependency(txn, packageID, dep.name);
|
||||
}
|
||||
txn.commit();
|
||||
}
|
||||
{
|
||||
auto txn = m_storage->providedLibs.getRWTransaction();
|
||||
auto txn = storage.providedLibs.getRWTransaction(txnHandle);
|
||||
for (const auto &lib : package->libprovides) {
|
||||
removeLibDependency(txn, packageID, lib);
|
||||
}
|
||||
txn.commit();
|
||||
}
|
||||
{
|
||||
auto txn = m_storage->requiredLibs.getRWTransaction();
|
||||
auto txn = storage.requiredLibs.getRWTransaction(txnHandle);
|
||||
for (const auto &lib : package->libdepends) {
|
||||
removeLibDependency(txn, packageID, lib);
|
||||
}
|
||||
txn.commit();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -253,39 +250,36 @@ static void addLibDependency(LibraryDependencyStorage::RWTransaction &txn, Stora
|
|||
txn.put(newDependency);
|
||||
}
|
||||
|
||||
void Database::addPackageDependencies(StorageID packageID, const std::shared_ptr<Package> &package)
|
||||
static void addPackageDependencies(DatabaseStorage &storage, const std::shared_ptr<LMDBSafe::MDBRWTransaction> &txnHandle, StorageID packageID,
|
||||
const std::shared_ptr<Package> &package)
|
||||
{
|
||||
{
|
||||
auto txn = m_storage->providedDeps.getRWTransaction();
|
||||
auto txn = storage.providedDeps.getRWTransaction(txnHandle);
|
||||
addDependency(txn, packageID, package->name, package->version);
|
||||
for (const auto &dep : package->provides) {
|
||||
addDependency(txn, packageID, dep.name, dep.version, dep.mode);
|
||||
}
|
||||
txn.commit();
|
||||
}
|
||||
{
|
||||
auto txn = m_storage->requiredDeps.getRWTransaction();
|
||||
auto txn = storage.requiredDeps.getRWTransaction(txnHandle);
|
||||
for (const auto &dep : package->dependencies) {
|
||||
addDependency(txn, packageID, dep.name, dep.version, dep.mode);
|
||||
}
|
||||
for (const auto &dep : package->optionalDependencies) {
|
||||
addDependency(txn, packageID, dep.name, dep.version, dep.mode);
|
||||
}
|
||||
txn.commit();
|
||||
}
|
||||
{
|
||||
auto txn = m_storage->providedLibs.getRWTransaction();
|
||||
auto txn = storage.providedLibs.getRWTransaction(txnHandle);
|
||||
for (const auto &lib : package->libprovides) {
|
||||
addLibDependency(txn, packageID, lib);
|
||||
}
|
||||
txn.commit();
|
||||
}
|
||||
{
|
||||
auto txn = m_storage->requiredLibs.getRWTransaction();
|
||||
auto txn = storage.requiredLibs.getRWTransaction(txnHandle);
|
||||
for (const auto &lib : package->libdepends) {
|
||||
addLibDependency(txn, packageID, lib);
|
||||
}
|
||||
txn.commit();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -472,9 +466,11 @@ StorageID Database::findBasePackageWithID(const std::string &packageName, Packag
|
|||
void Database::removePackage(const std::string &packageName)
|
||||
{
|
||||
const auto lock = std::unique_lock(m_storage->updateMutex);
|
||||
const auto [packageID, package] = m_storage->packageCache.retrieve(*m_storage, packageName);
|
||||
auto txn = m_storage->packages.getRWTransaction();
|
||||
const auto [packageID, package] = m_storage->packageCache.retrieve(*m_storage, &txn, packageName);
|
||||
if (package) {
|
||||
removePackageDependencies(packageID, package);
|
||||
removePackageDependencies(*m_storage, txn.getTransactionHandle(), packageID, package);
|
||||
txn.commit();
|
||||
m_storage->packageCache.invalidate(*m_storage, packageName);
|
||||
}
|
||||
}
|
||||
|
@ -485,14 +481,16 @@ StorageID Database::updatePackage(const std::shared_ptr<Package> &package)
|
|||
return 0;
|
||||
}
|
||||
const auto lock = std::unique_lock(m_storage->updateMutex);
|
||||
const auto res = m_storage->packageCache.store(*m_storage, package, false);
|
||||
auto txn = m_storage->packages.getRWTransaction();
|
||||
const auto res = m_storage->packageCache.store(*m_storage, txn, package, false);
|
||||
if (!res.updated) {
|
||||
return res.id;
|
||||
}
|
||||
if (res.oldEntry) {
|
||||
removePackageDependencies(res.id, res.oldEntry);
|
||||
removePackageDependencies(*m_storage, txn.getTransactionHandle(), res.id, res.oldEntry);
|
||||
}
|
||||
addPackageDependencies(res.id, package);
|
||||
addPackageDependencies(*m_storage, txn.getTransactionHandle(), res.id, package);
|
||||
txn.commit();
|
||||
return res.id;
|
||||
}
|
||||
|
||||
|
@ -502,11 +500,13 @@ StorageID Database::forceUpdatePackage(const std::shared_ptr<Package> &package)
|
|||
return 0;
|
||||
}
|
||||
const auto lock = std::unique_lock(m_storage->updateMutex);
|
||||
const auto res = m_storage->packageCache.store(*m_storage, package, true);
|
||||
auto txn = m_storage->packages.getRWTransaction();
|
||||
const auto res = m_storage->packageCache.store(*m_storage, txn, package, true);
|
||||
if (res.oldEntry) {
|
||||
removePackageDependencies(res.id, res.oldEntry);
|
||||
removePackageDependencies(*m_storage, txn.getTransactionHandle(), res.id, res.oldEntry);
|
||||
}
|
||||
addPackageDependencies(res.id, package);
|
||||
addPackageDependencies(*m_storage, txn.getTransactionHandle(), res.id, package);
|
||||
txn.commit();
|
||||
return res.id;
|
||||
}
|
||||
|
||||
|
@ -885,7 +885,7 @@ PackageSpec LibPkg::PackageUpdater::findPackageWithID(const std::string &package
|
|||
StorageID PackageUpdater::update(const std::shared_ptr<Package> &package)
|
||||
{
|
||||
const auto &storage = m_database.m_storage;
|
||||
const auto res = storage->packageCache.store(*m_database.m_storage, m_d->packagesTxn, package);
|
||||
const auto res = storage->packageCache.store(*m_database.m_storage, m_d->packagesTxn, package, true);
|
||||
m_d->update(res, package);
|
||||
return res.id;
|
||||
}
|
||||
|
|
|
@ -194,10 +194,6 @@ struct LIBPKG_EXPORT Database : public ReflectiveRapidJSON::JsonSerializable<Dat
|
|||
PackageLocation locatePackage(const std::string &packageName) const;
|
||||
std::string filesPathFromRegularPath() const;
|
||||
|
||||
private:
|
||||
void removePackageDependencies(StorageID packageID, const std::shared_ptr<Package> &package);
|
||||
void addPackageDependencies(StorageID packageID, const std::shared_ptr<Package> &package);
|
||||
|
||||
public:
|
||||
std::string name;
|
||||
std::string path;
|
||||
|
|
|
@ -130,55 +130,8 @@ auto StorageCache<StorageEntriesType, StorageType, SpecType>::retrieve(Storage &
|
|||
}
|
||||
|
||||
template <typename StorageEntriesType, typename StorageType, typename SpecType>
|
||||
auto StorageCache<StorageEntriesType, StorageType, SpecType>::store(Storage &storage, const std::shared_ptr<Entry> &entry, bool force) -> StoreResult
|
||||
{
|
||||
// check for package in cache
|
||||
using CacheEntry = typename Entries::StorageEntry;
|
||||
using CacheRef = typename Entries::Ref;
|
||||
const auto ref = CacheRef(storage, entry);
|
||||
auto res = StorageCache::StoreResult();
|
||||
auto lock = std::unique_lock(m_mutex);
|
||||
auto *cacheEntry = m_entries.find(ref);
|
||||
if (cacheEntry) {
|
||||
res.id = cacheEntry->id;
|
||||
res.oldEntry = cacheEntry->entry;
|
||||
if (cacheEntry->entry == entry && !force) {
|
||||
// do nothing if cached package is the same as specified one
|
||||
return res;
|
||||
} else {
|
||||
// retain certain information obtained from package contents if this is actually the same package as before
|
||||
entry->addDepsAndProvidesFromOtherPackage(*cacheEntry->entry);
|
||||
}
|
||||
}
|
||||
lock.unlock();
|
||||
// check for package in storage
|
||||
auto txn = storage.packages.getRWTransaction();
|
||||
if (!res.oldEntry) {
|
||||
res.oldEntry = std::make_shared<Entry>();
|
||||
if ((res.id = txn.template get<0>(entry->name, *res.oldEntry))) {
|
||||
entry->addDepsAndProvidesFromOtherPackage(*res.oldEntry);
|
||||
} else {
|
||||
res.oldEntry.reset();
|
||||
}
|
||||
}
|
||||
// update package in storage
|
||||
res.id = txn.put(*entry, res.id);
|
||||
// update cache entry
|
||||
lock = std::unique_lock(m_mutex);
|
||||
if (cacheEntry) {
|
||||
cacheEntry->ref.entryName = &entry->name;
|
||||
} else {
|
||||
cacheEntry = &m_entries.insert(CacheEntry(ref, res.id));
|
||||
}
|
||||
cacheEntry->entry = entry;
|
||||
lock.unlock();
|
||||
txn.commit();
|
||||
res.updated = true;
|
||||
return res;
|
||||
}
|
||||
|
||||
template <typename StorageEntriesType, typename StorageType, typename SpecType>
|
||||
auto StorageCache<StorageEntriesType, StorageType, SpecType>::store(Storage &storage, RWTxn &txn, const std::shared_ptr<Entry> &entry) -> StoreResult
|
||||
auto StorageCache<StorageEntriesType, StorageType, SpecType>::store(Storage &storage, RWTxn &txn, const std::shared_ptr<Entry> &entry, bool force)
|
||||
-> StoreResult
|
||||
{
|
||||
// check for package in cache
|
||||
using CacheEntry = typename Entries::StorageEntry;
|
||||
|
@ -191,6 +144,10 @@ auto StorageCache<StorageEntriesType, StorageType, SpecType>::store(Storage &sto
|
|||
auto lock = std::unique_lock(m_mutex);
|
||||
auto *cacheEntry = m_entries.find(ref);
|
||||
if (cacheEntry) {
|
||||
if (cacheEntry->entry == entry && !force) {
|
||||
// do nothing if cached package is the same as specified one
|
||||
return res;
|
||||
}
|
||||
// retain certain information obtained from package contents if this is actually the same package as before
|
||||
res.id = cacheEntry->id;
|
||||
entry->addDepsAndProvidesFromOtherPackage(*(res.oldEntry = cacheEntry->entry));
|
||||
|
|
|
@ -151,8 +151,7 @@ template <typename StorageEntriesType, typename StorageType, typename SpecType>
|
|||
SpecType retrieve(Storage &storage, StorageID storageID);
|
||||
SpecType retrieve(Storage &storage, RWTxn *, const std::string &entryName);
|
||||
SpecType retrieve(Storage &storage, const std::string &entryName);
|
||||
StoreResult store(Storage &storage, const std::shared_ptr<Entry> &entry, bool force);
|
||||
StoreResult store(Storage &storage, RWTxn &txn, const std::shared_ptr<Entry> &entry);
|
||||
StoreResult store(Storage &storage, RWTxn &txn, const std::shared_ptr<Entry> &entry, bool force);
|
||||
bool invalidate(Storage &storage, const std::string &entryName);
|
||||
void clear(Storage &storage);
|
||||
void clearCacheOnly(Storage &storage);
|
||||
|
|
Loading…
Reference in New Issue