| // 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. |
| |
| #include "smbprovider/metadata_cache.h" |
| |
| #include <base/time/tick_clock.h> |
| |
| namespace smbprovider { |
| |
| MetadataCache::MetadataCache(base::TickClock* tick_clock, |
| base::TimeDelta entry_lifetime, |
| Mode mode) |
| : tick_clock_(tick_clock), entry_lifetime_(entry_lifetime), mode_(mode) {} |
| |
| MetadataCache::~MetadataCache() = default; |
| |
| void MetadataCache::AddEntry(const DirectoryEntry& entry) { |
| // NowTicks() is non-decreasing so any value we get will always be at |
| // at least equal to the higest version we've seen before. |
| max_expiration_time_ = tick_clock_->NowTicks() + entry_lifetime_; |
| cache_[entry.full_path] = CacheEntry(entry, max_expiration_time_); |
| } |
| |
| bool MetadataCache::FindEntry(const std::string& full_path, |
| DirectoryEntry* out_entry) { |
| if (!IsEnabled()) { |
| return false; |
| } |
| |
| auto entry_iter = cache_.find(full_path); |
| if (entry_iter == cache_.end()) { |
| return false; |
| } |
| |
| if (IsExpired(entry_iter->second)) { |
| cache_.erase(entry_iter); |
| return false; |
| } |
| |
| *out_entry = entry_iter->second.entry; |
| return true; |
| } |
| |
| void MetadataCache::ClearAll() { |
| cache_.clear(); |
| } |
| |
| bool MetadataCache::IsEmpty() const { |
| return cache_.empty(); |
| } |
| |
| bool MetadataCache::RemoveEntry(const std::string& entry_path) { |
| return cache_.erase(entry_path) > 0; |
| } |
| |
| void MetadataCache::PurgeExpiredEntries() { |
| if (IsEmpty()) { |
| // Nothing to do if it is already empty. |
| return; |
| } |
| |
| // If all entries are expired, just clear the entire map. |
| if (AreAllEntriesExpired()) { |
| ClearAll(); |
| return; |
| } |
| |
| // Otherwise iterate through the map removing the expired entries. |
| const base::TimeTicks threshold = tick_clock_->NowTicks(); |
| |
| auto it = cache_.cbegin(); |
| while (it != cache_.cend()) { |
| if (MetadataCache::IsExpired(it->second, threshold)) { |
| it = cache_.erase(it); |
| } else { |
| ++it; |
| } |
| } |
| } |
| |
| bool MetadataCache::IsExpired(const CacheEntry& cache_entry, |
| base::TimeTicks threshold) { |
| return threshold > cache_entry.expiration_time; |
| } |
| |
| bool MetadataCache::IsExpired( |
| const MetadataCache::CacheEntry& cache_entry) const { |
| return MetadataCache::IsExpired(cache_entry, tick_clock_->NowTicks()); |
| } |
| |
| bool MetadataCache::AreAllEntriesExpired() const { |
| return tick_clock_->NowTicks() > max_expiration_time_; |
| } |
| |
| bool MetadataCache::IsEnabled() const { |
| return mode_ != Mode::kDisabled; |
| } |
| |
| } // namespace smbprovider |