Martchus
7ade757c8d
* Only lock the config for writing the reloading the config file * Make sure all write operations to the database acquire an "update mutex" to ensure only one write operation happens at a time * Do *not* acquire any additional locks when reading from a database as it should be safe to do so even when a write operation happens because * LMDB read and write transactions can happen at the same time * The package cache has its own mutex anyways * Write ops to the package cache try to lock the "update mutex" to prevent writing "old" data to the cache during updates * Make "lastUpdate" atomic to avoid locking the config when accessing it
67 lines
2.5 KiB
C++
67 lines
2.5 KiB
C++
#ifndef LIBPKG_DATA_STORAGE_PRIVATE_H
|
|
#define LIBPKG_DATA_STORAGE_PRIVATE_H
|
|
|
|
#include "./package.h"
|
|
#include "./storagegeneric.h"
|
|
|
|
#include <mutex>
|
|
|
|
namespace LibPkg {
|
|
|
|
using PackageStorage = LMDBSafe::TypedDBI<Package, LMDBSafe::index_on<Package, std::string, &Package::name>>;
|
|
using DependencyStorage = LMDBSafe::TypedDBI<DatabaseDependency, LMDBSafe::index_on<Dependency, std::string, &DatabaseDependency::name>>;
|
|
using LibraryDependencyStorage
|
|
= LMDBSafe::TypedDBI<DatabaseLibraryDependency, LMDBSafe::index_on<DatabaseLibraryDependency, std::string, &DatabaseLibraryDependency::name>>;
|
|
using PackageCacheRef = StorageCacheRef<DatabaseStorage, Package>;
|
|
using PackageCacheEntry = StorageCacheEntry<PackageCacheRef, Package>;
|
|
using PackageCacheEntries = StorageCacheEntries<PackageCacheEntry>;
|
|
using PackageCacheEntryByID = typename PackageCacheEntries::ByID::result_type;
|
|
using PackageCache = StorageCache<PackageCacheEntries, PackageStorage, PackageSpec>;
|
|
|
|
extern template struct StorageCacheRef<DatabaseStorage, Package>;
|
|
extern template struct StorageCacheEntry<PackageCacheRef, Package>;
|
|
extern template class StorageCacheEntries<PackageCacheEntry>;
|
|
extern template struct StorageCache<PackageCacheEntries, PackageStorage, PackageSpec>;
|
|
|
|
struct StorageDistribution {
|
|
explicit StorageDistribution(const char *path, std::uint32_t maxDbs);
|
|
|
|
std::unique_ptr<DatabaseStorage> forDatabase(std::string_view uniqueDatabaseName);
|
|
PackageCache &packageCache();
|
|
|
|
private:
|
|
std::shared_ptr<LMDBSafe::MDBEnv> m_env;
|
|
PackageCache m_packageCache;
|
|
};
|
|
|
|
inline std::unique_ptr<DatabaseStorage> StorageDistribution::forDatabase(std::string_view uniqueDatabaseName)
|
|
{
|
|
return std::make_unique<DatabaseStorage>(m_env, m_packageCache, uniqueDatabaseName);
|
|
}
|
|
|
|
inline PackageCache &StorageDistribution::packageCache()
|
|
{
|
|
return m_packageCache;
|
|
}
|
|
|
|
struct DatabaseStorage {
|
|
explicit DatabaseStorage(const std::shared_ptr<LMDBSafe::MDBEnv> &env, PackageCache &packageCache, std::string_view uniqueDatabaseName);
|
|
PackageCache &packageCache;
|
|
PackageStorage packages;
|
|
DependencyStorage providedDeps;
|
|
DependencyStorage requiredDeps;
|
|
LibraryDependencyStorage providedLibs;
|
|
LibraryDependencyStorage requiredLibs;
|
|
std::mutex updateMutex; // must be acquired to update packages, concurrent reads should still be possible
|
|
|
|
private:
|
|
std::shared_ptr<LMDBSafe::MDBEnv> m_env;
|
|
};
|
|
|
|
std::size_t hash_value(const PackageCacheRef &ref);
|
|
std::size_t hash_value(const PackageCacheEntryByID &entryByID);
|
|
|
|
} // namespace LibPkg
|
|
|
|
#endif // LIBPKG_DATA_STORAGE_PRIVATE_H
|