| 211 | } |
| 212 | |
| 213 | Status PersistentCacheImpl::Read(const Slice& key, size_t offset, size_t length, Slice* content, |
| 214 | SstDataScratch* scratch) { |
| 215 | uint64_t cache_id; |
| 216 | bool ok = metadata_.Lookup(key, &cache_id); |
| 217 | if (!ok) { |
| 218 | stats_->cache_misses.Inc(); |
| 219 | return Status::NotFound("persistent cache: cache id not found"); |
| 220 | } |
| 221 | |
| 222 | auto file = metadata_.Lookup(cache_id); |
| 223 | if (!file) { |
| 224 | // this can happen because the file index and cache file index are |
| 225 | // different, and the cache file might be removed between the two lookups |
| 226 | stats_->cache_misses.Inc(); |
| 227 | return Status::NotFound("persistent cache: cache file not found"); |
| 228 | } |
| 229 | |
| 230 | assert(file->refs_); |
| 231 | auto s = file->Read(offset, length, content, scratch); |
| 232 | file.reset(); |
| 233 | |
| 234 | if (!s.ok()) { |
| 235 | stats_->cache_misses.Inc(); |
| 236 | stats_->cache_errors.Inc(); |
| 237 | return s; |
| 238 | } |
| 239 | |
| 240 | stats_->read_throughput.Add(content->size()); |
| 241 | stats_->cache_hits.Inc(); |
| 242 | return Status::OK(); |
| 243 | } |
| 244 | |
| 245 | void PersistentCacheImpl::ForceEvict(const Slice& key) { |
| 246 | std::unique_ptr<CacheFile> file{metadata_.ForceEvict(key)}; |