Coverage Report

Created: 2024-10-29 12:15

/root/bitcoin/src/leveldb/db/table_cache.cc
Line
Count
Source (jump to first uncovered line)
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
0
static void DeleteEntry(const Slice& key, void* value) {
20
0
  TableAndFile* tf = reinterpret_cast<TableAndFile*>(value);
21
0
  delete tf->table;
22
0
  delete tf->file;
23
0
  delete tf;
24
0
}
25
26
0
static void UnrefEntry(void* arg1, void* arg2) {
27
0
  Cache* cache = reinterpret_cast<Cache*>(arg1);
28
0
  Cache::Handle* h = reinterpret_cast<Cache::Handle*>(arg2);
29
0
  cache->Release(h);
30
0
}
31
32
TableCache::TableCache(const std::string& dbname, const Options& options,
33
                       int entries)
34
0
    : env_(options.env),
35
0
      dbname_(dbname),
36
0
      options_(options),
37
0
      cache_(NewLRUCache(entries)) {}
38
39
2
TableCache::~TableCache() { delete cache_; }
40
41
Status TableCache::FindTable(uint64_t file_number, uint64_t file_size,
42
0
                             Cache::Handle** handle) {
43
0
  Status s;
44
0
  char buf[sizeof(file_number)];
45
0
  EncodeFixed64(buf, file_number);
46
0
  Slice key(buf, sizeof(buf));
47
0
  *handle = cache_->Lookup(key);
48
0
  if (*handle == nullptr) {
49
0
    std::string fname = TableFileName(dbname_, file_number);
50
0
    RandomAccessFile* file = nullptr;
51
0
    Table* table = nullptr;
52
0
    s = env_->NewRandomAccessFile(fname, &file);
53
0
    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
0
    if (s.ok()) {
60
0
      s = Table::Open(options_, file, file_size, &table);
61
0
    }
62
63
0
    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
0
    } else {
69
0
      TableAndFile* tf = new TableAndFile;
70
0
      tf->file = file;
71
0
      tf->table = table;
72
0
      *handle = cache_->Insert(key, tf, 1, &DeleteEntry);
73
0
    }
74
0
  }
75
0
  return s;
76
0
}
77
78
Iterator* TableCache::NewIterator(const ReadOptions& options,
79
                                  uint64_t file_number, uint64_t file_size,
80
0
                                  Table** tableptr) {
81
0
  if (tableptr != nullptr) {
82
0
    *tableptr = nullptr;
83
0
  }
84
85
0
  Cache::Handle* handle = nullptr;
86
0
  Status s = FindTable(file_number, file_size, &handle);
87
0
  if (!s.ok()) {
88
0
    return NewErrorIterator(s);
89
0
  }
90
91
0
  Table* table = reinterpret_cast<TableAndFile*>(cache_->Value(handle))->table;
92
0
  Iterator* result = table->NewIterator(options);
93
0
  result->RegisterCleanup(&UnrefEntry, cache_, handle);
94
0
  if (tableptr != nullptr) {
95
0
    *tableptr = table;
96
0
  }
97
0
  return result;
98
0
}
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
0
                                             const Slice&)) {
104
0
  Cache::Handle* handle = nullptr;
105
0
  Status s = FindTable(file_number, file_size, &handle);
106
0
  if (s.ok()) {
107
0
    Table* t = reinterpret_cast<TableAndFile*>(cache_->Value(handle))->table;
108
0
    s = t->InternalGet(options, k, arg, handle_result);
109
0
    cache_->Release(handle);
110
0
  }
111
0
  return s;
112
0
}
113
114
0
void TableCache::Evict(uint64_t file_number) {
115
0
  char buf[sizeof(file_number)];
116
0
  EncodeFixed64(buf, file_number);
117
0
  cache_->Erase(Slice(buf, sizeof(buf)));
118
0
}
119
120
}  // namespace leveldb