| 832 | } |
| 833 | |
| 834 | int64_t DataCache::Partition::Lookup(const CacheKey& cache_key, int64_t bytes_to_read, |
| 835 | uint8_t* buffer) { |
| 836 | DCHECK(!closed_); |
| 837 | DCHECK(trace_replay_ ? buffer == nullptr : buffer != nullptr); |
| 838 | Slice key = cache_key.ToSlice(); |
| 839 | Cache::UniqueHandle handle(meta_cache_->Lookup(key)); |
| 840 | |
| 841 | if (handle.get() == nullptr) { |
| 842 | Trace(trace::EventType::MISS, cache_key, bytes_to_read, /*entry_len=*/-1); |
| 843 | return 0; |
| 844 | } |
| 845 | |
| 846 | // Read from the backing file. |
| 847 | CacheEntry entry(meta_cache_->Value(handle)); |
| 848 | |
| 849 | Trace(trace::EventType::HIT, cache_key, bytes_to_read, entry.len()); |
| 850 | |
| 851 | bytes_to_read = min(entry.len(), bytes_to_read); |
| 852 | // Skip the actual reads if doing trace replay |
| 853 | if (LIKELY(!trace_replay_)) { |
| 854 | CacheFile* cache_file = entry.file(); |
| 855 | VLOG(3) << Substitute("Reading file $0 offset $1 len $2 checksum $3 bytes_to_read $4", |
| 856 | cache_file->path(), entry.offset(), entry.len(), entry.checksum(), bytes_to_read); |
| 857 | bool read_success; |
| 858 | { |
| 859 | ScopedHistogramTimer read_timer(read_latency_); |
| 860 | read_success = cache_file->Read(entry.offset(), buffer, bytes_to_read); |
| 861 | } |
| 862 | if (UNLIKELY(!read_success)) { |
| 863 | meta_cache_->Erase(key); |
| 864 | return 0; |
| 865 | } |
| 866 | |
| 867 | // Verify checksum if enabled. Delete entry on checksum mismatch. |
| 868 | if (FLAGS_data_cache_checksum && bytes_to_read == entry.len() && |
| 869 | !VerifyChecksum("read", entry, buffer, bytes_to_read)) { |
| 870 | meta_cache_->Erase(key); |
| 871 | return 0; |
| 872 | } |
| 873 | } |
| 874 | return bytes_to_read; |
| 875 | } |
| 876 | |
| 877 | bool DataCache::Partition::HandleExistingEntry(const Slice& key, |
| 878 | const Cache::UniqueHandle& handle, const uint8_t* buffer, int64_t buffer_len) { |