#pragma once #include #include #include #include #include #include namespace DB { class AccessChangesNotifier; /// Implementation of IAccessStorage which keeps all data in memory. class MemoryAccessStorage : public IAccessStorage { public: static constexpr char STORAGE_TYPE[] = "memory"; explicit MemoryAccessStorage(const String & storage_name_, AccessChangesNotifier & changes_notifier_, bool allow_backup_); const char * getStorageType() const override { return STORAGE_TYPE; } /// Inserts an entity with a specified ID. /// If `replace_if_exists == true` it can replace an existing entry with such ID and also remove an existing entry /// with such name & type. bool insertWithID(const UUID & id, const AccessEntityPtr & new_entity, bool replace_if_exists, bool throw_if_exists); /// Removes all entities except a specified list. void removeAllExcept(const std::vector & ids_to_keep); /// Sets all entities at once. void setAll(const std::vector & all_entities); void setAll(const std::vector> & all_entities); bool exists(const UUID & id) const override; bool isBackupAllowed() const override { return backup_allowed; } void restoreFromBackup(RestorerFromBackup & restorer) override; private: std::optional findImpl(AccessEntityType type, const String & name) const override; std::vector findAllImpl(AccessEntityType type) const override; AccessEntityPtr readImpl(const UUID & id, bool throw_if_not_exists) const override; std::optional insertImpl(const AccessEntityPtr & entity, bool replace_if_exists, bool throw_if_exists) override; bool removeImpl(const UUID & id, bool throw_if_not_exists) override; bool updateImpl(const UUID & id, const UpdateFunc & update_func, bool throw_if_not_exists) override; bool insertNoLock(const UUID & id, const AccessEntityPtr & entity, bool replace_if_exists, bool throw_if_exists) TSA_REQUIRES(mutex); bool removeNoLock(const UUID & id, bool throw_if_not_exists) TSA_REQUIRES(mutex); bool updateNoLock(const UUID & id, const UpdateFunc & update_func, bool throw_if_not_exists) TSA_REQUIRES(mutex); void removeAllExceptNoLock(const std::vector & ids_to_keep) TSA_REQUIRES(mutex); struct Entry { UUID id; AccessEntityPtr entity; }; mutable std::mutex mutex; std::unordered_map entries_by_id TSA_GUARDED_BY(mutex); /// We want to search entries both by ID and by the pair of name and type. std::unordered_map entries_by_name_and_type[static_cast(AccessEntityType::MAX)] TSA_GUARDED_BY(mutex); AccessChangesNotifier & changes_notifier; const bool backup_allowed = false; }; }