Branch data Line data Source code
# 1 : : // Copyright (c) 2011 The LevelDB Authors. All rights reserved.
# 2 : : // Use of this source code is governed by a BSD-style license that can be
# 3 : : // found in the LICENSE file. See the AUTHORS file for names of contributors.
# 4 : :
# 5 : : #include "db/table_cache.h"
# 6 : :
# 7 : : #include "db/filename.h"
# 8 : : #include "leveldb/env.h"
# 9 : : #include "leveldb/table.h"
# 10 : : #include "util/coding.h"
# 11 : :
# 12 : : namespace leveldb {
# 13 : :
# 14 : : struct TableAndFile {
# 15 : : RandomAccessFile* file;
# 16 : : Table* table;
# 17 : : };
# 18 : :
# 19 : 1439 : static void DeleteEntry(const Slice& key, void* value) {
# 20 : 1439 : TableAndFile* tf = reinterpret_cast<TableAndFile*>(value);
# 21 : 1439 : delete tf->table;
# 22 : 1439 : delete tf->file;
# 23 : 1439 : delete tf;
# 24 : 1439 : }
# 25 : :
# 26 : 2735 : static void UnrefEntry(void* arg1, void* arg2) {
# 27 : 2735 : Cache* cache = reinterpret_cast<Cache*>(arg1);
# 28 : 2735 : Cache::Handle* h = reinterpret_cast<Cache::Handle*>(arg2);
# 29 : 2735 : cache->Release(h);
# 30 : 2735 : }
# 31 : :
# 32 : : TableCache::TableCache(const std::string& dbname, const Options& options,
# 33 : : int entries)
# 34 : : : env_(options.env),
# 35 : : dbname_(dbname),
# 36 : : options_(options),
# 37 : 1641 : cache_(NewLRUCache(entries)) {}
# 38 : :
# 39 : 1641 : TableCache::~TableCache() { delete cache_; }
# 40 : :
# 41 : : Status TableCache::FindTable(uint64_t file_number, uint64_t file_size,
# 42 : 2451892 : Cache::Handle** handle) {
# 43 : 2451892 : Status s;
# 44 : 2451892 : char buf[sizeof(file_number)];
# 45 : 2451892 : EncodeFixed64(buf, file_number);
# 46 : 2451892 : Slice key(buf, sizeof(buf));
# 47 : 2451892 : *handle = cache_->Lookup(key);
# 48 [ + + ]: 2451892 : if (*handle == nullptr) {
# 49 : 1439 : std::string fname = TableFileName(dbname_, file_number);
# 50 : 1439 : RandomAccessFile* file = nullptr;
# 51 : 1439 : Table* table = nullptr;
# 52 : 1439 : s = env_->NewRandomAccessFile(fname, &file);
# 53 [ - + ]: 1439 : if (!s.ok()) {
# 54 : 0 : std::string old_fname = SSTTableFileName(dbname_, file_number);
# 55 [ # # ]: 0 : if (env_->NewRandomAccessFile(old_fname, &file).ok()) {
# 56 : 0 : s = Status::OK();
# 57 : 0 : }
# 58 : 0 : }
# 59 [ + - ]: 1439 : if (s.ok()) {
# 60 : 1439 : s = Table::Open(options_, file, file_size, &table);
# 61 : 1439 : }
# 62 : :
# 63 [ - + ]: 1439 : if (!s.ok()) {
# 64 : 0 : assert(table == nullptr);
# 65 : 0 : delete file;
# 66 : : // We do not cache error results so that if the error is transient,
# 67 : : // or somebody repairs the file, we recover automatically.
# 68 : 1439 : } else {
# 69 : 1439 : TableAndFile* tf = new TableAndFile;
# 70 : 1439 : tf->file = file;
# 71 : 1439 : tf->table = table;
# 72 : 1439 : *handle = cache_->Insert(key, tf, 1, &DeleteEntry);
# 73 : 1439 : }
# 74 : 1439 : }
# 75 : 2451892 : return s;
# 76 : 2451892 : }
# 77 : :
# 78 : : Iterator* TableCache::NewIterator(const ReadOptions& options,
# 79 : : uint64_t file_number, uint64_t file_size,
# 80 : 2735 : Table** tableptr) {
# 81 [ + + ]: 2735 : if (tableptr != nullptr) {
# 82 : 17 : *tableptr = nullptr;
# 83 : 17 : }
# 84 : :
# 85 : 2735 : Cache::Handle* handle = nullptr;
# 86 : 2735 : Status s = FindTable(file_number, file_size, &handle);
# 87 [ - + ]: 2735 : if (!s.ok()) {
# 88 : 0 : return NewErrorIterator(s);
# 89 : 0 : }
# 90 : :
# 91 : 2735 : Table* table = reinterpret_cast<TableAndFile*>(cache_->Value(handle))->table;
# 92 : 2735 : Iterator* result = table->NewIterator(options);
# 93 : 2735 : result->RegisterCleanup(&UnrefEntry, cache_, handle);
# 94 [ + + ]: 2735 : if (tableptr != nullptr) {
# 95 : 17 : *tableptr = table;
# 96 : 17 : }
# 97 : 2735 : return result;
# 98 : 2735 : }
# 99 : :
# 100 : : Status TableCache::Get(const ReadOptions& options, uint64_t file_number,
# 101 : : uint64_t file_size, const Slice& k, void* arg,
# 102 : : void (*handle_result)(void*, const Slice&,
# 103 : 2449157 : const Slice&)) {
# 104 : 2449157 : Cache::Handle* handle = nullptr;
# 105 : 2449157 : Status s = FindTable(file_number, file_size, &handle);
# 106 [ + - ]: 2449157 : if (s.ok()) {
# 107 : 2449157 : Table* t = reinterpret_cast<TableAndFile*>(cache_->Value(handle))->table;
# 108 : 2449157 : s = t->InternalGet(options, k, arg, handle_result);
# 109 : 2449157 : cache_->Release(handle);
# 110 : 2449157 : }
# 111 : 2449157 : return s;
# 112 : 2449157 : }
# 113 : :
# 114 : 267 : void TableCache::Evict(uint64_t file_number) {
# 115 : 267 : char buf[sizeof(file_number)];
# 116 : 267 : EncodeFixed64(buf, file_number);
# 117 : 267 : cache_->Erase(Slice(buf, sizeof(buf)));
# 118 : 267 : }
# 119 : :
# 120 : : } // namespace leveldb
|