| // Copyright 2018 The Chromium OS Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef SMBPROVIDER_METADATA_CACHE_H_ |
| #define SMBPROVIDER_METADATA_CACHE_H_ |
| |
| #include <string> |
| #include <unordered_map> |
| |
| #include <base/macros.h> |
| #include <base/time/time.h> |
| |
| #include "smbprovider/proto.h" |
| |
| namespace base { |
| class TickClock; |
| } |
| |
| namespace smbprovider { |
| |
| // Maintains a cache of file and directory metadata. This is the data |
| // that is returned by stat(); name, entry type, size, date modified. |
| // |
| // The libsmbclient API can return all metadata while enumerating a |
| // directory, but the Chrome FileSystemProvider API makes per entry |
| // requests for metadata. This cache will store the results found |
| // when reading a directory, then use the cache to attempt to satisfy |
| // requests for metadata. |
| class MetadataCache { |
| public: |
| enum class Mode { |
| kStandard, // Standard Cache behavior. |
| kDisabled // All lookups are cache misses. |
| }; |
| |
| // |entry_lifetime| determines how long an entry remains valid in the cache. |
| MetadataCache(base::TickClock* tick_clock, |
| base::TimeDelta entry_lifetime, |
| Mode mode); |
| MetadataCache(const MetadataCache&) = delete; |
| MetadataCache& operator=(const MetadataCache&) = delete; |
| |
| ~MetadataCache(); |
| |
| MetadataCache& operator=(MetadataCache&& other) = default; |
| |
| // Adds an entry to the cache. |
| void AddEntry(const DirectoryEntry& entry); |
| |
| // Finds an entry at |full_path|. If found, returns true and out_entry |
| // is set. |full_path| is a full smb url. If an entry is found but it |
| // is expired, it is removed from the cache. |
| bool FindEntry(const std::string& full_path, DirectoryEntry* out_entry); |
| |
| // Deletes all entries from the cache. |
| void ClearAll(); |
| |
| // Returns true if the cache is empty. |
| bool IsEmpty() const; |
| |
| // Removes the entry at |entry_path| from the cache. |entry_cache| is a |
| // full smb url. |
| bool RemoveEntry(const std::string& entry_path); |
| |
| // Removes all entries in the cache that have expired. |
| void PurgeExpiredEntries(); |
| |
| private: |
| struct CacheEntry { |
| CacheEntry() = default; |
| CacheEntry(const DirectoryEntry& entry, base::TimeTicks expiration_time) |
| : entry(entry), expiration_time(expiration_time) {} |
| CacheEntry(const CacheEntry&) = delete; |
| CacheEntry& operator=(const CacheEntry&) = delete; |
| |
| CacheEntry& operator=(CacheEntry&& other) = default; |
| |
| DirectoryEntry entry; |
| base::TimeTicks expiration_time; |
| |
| }; |
| |
| // Returns true if the expiration time of this entry has passed. |
| bool IsExpired(const CacheEntry& cache_entry) const; |
| static bool IsExpired(const CacheEntry& cache_entry, |
| base::TimeTicks threshold); |
| |
| // Returns true if all the entries in the cache are expired. |
| bool AreAllEntriesExpired() const; |
| |
| // Returns true if the cache should act as a cache. |
| bool IsEnabled() const; |
| |
| std::unordered_map<std::string, CacheEntry> cache_; |
| base::TickClock* tick_clock_; // Not owned |
| base::TimeDelta entry_lifetime_; |
| base::TimeTicks max_expiration_time_; |
| Mode mode_; |
| }; |
| |
| } // namespace smbprovider |
| |
| #endif // SMBPROVIDER_METADATA_CACHE_H_ |