leveldb
table_cache.cc
Go to the documentation of this file.
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 {
17 };
18 
19 static void DeleteEntry(const Slice& key, void* value) {
20  TableAndFile* tf = reinterpret_cast<TableAndFile*>(value);
21  delete tf->table;
22  delete tf->file;
23  delete tf;
24 }
25 
26 static void UnrefEntry(void* arg1, void* arg2) {
27  Cache* cache = reinterpret_cast<Cache*>(arg1);
28  Cache::Handle* h = reinterpret_cast<Cache::Handle*>(arg2);
29  cache->Release(h);
30 }
31 
32 TableCache::TableCache(const std::string& dbname,
33  const Options* options,
34  int entries)
35  : env_(options->env),
36  dbname_(dbname),
37  options_(options),
38  cache_(NewLRUCache(entries)) {
39 }
40 
42  delete cache_;
43 }
44 
45 Status TableCache::FindTable(uint64_t file_number, uint64_t file_size,
46  Cache::Handle** handle) {
47  Status s;
48  char buf[sizeof(file_number)];
49  EncodeFixed64(buf, file_number);
50  Slice key(buf, sizeof(buf));
51  *handle = cache_->Lookup(key);
52  if (*handle == NULL) {
53  std::string fname = TableFileName(dbname_, file_number);
54  RandomAccessFile* file = NULL;
55  Table* table = NULL;
56  s = env_->NewRandomAccessFile(fname, &file);
57  if (!s.ok()) {
58  std::string old_fname = SSTTableFileName(dbname_, file_number);
59  if (env_->NewRandomAccessFile(old_fname, &file).ok()) {
60  s = Status::OK();
61  }
62  }
63  if (s.ok()) {
64  s = Table::Open(*options_, file, file_size, &table);
65  }
66 
67  if (!s.ok()) {
68  assert(table == NULL);
69  delete file;
70  // We do not cache error results so that if the error is transient,
71  // or somebody repairs the file, we recover automatically.
72  } else {
73  TableAndFile* tf = new TableAndFile;
74  tf->file = file;
75  tf->table = table;
76  *handle = cache_->Insert(key, tf, 1, &DeleteEntry);
77  }
78  }
79  return s;
80 }
81 
83  uint64_t file_number,
84  uint64_t file_size,
85  Table** tableptr) {
86  if (tableptr != NULL) {
87  *tableptr = NULL;
88  }
89 
90  Cache::Handle* handle = NULL;
91  Status s = FindTable(file_number, file_size, &handle);
92  if (!s.ok()) {
93  return NewErrorIterator(s);
94  }
95 
96  Table* table = reinterpret_cast<TableAndFile*>(cache_->Value(handle))->table;
97  Iterator* result = table->NewIterator(options);
98  result->RegisterCleanup(&UnrefEntry, cache_, handle);
99  if (tableptr != NULL) {
100  *tableptr = table;
101  }
102  return result;
103 }
104 
106  uint64_t file_number,
107  uint64_t file_size,
108  const Slice& k,
109  void* arg,
110  void (*saver)(void*, const Slice&, const Slice&)) {
111  Cache::Handle* handle = NULL;
112  Status s = FindTable(file_number, file_size, &handle);
113  if (s.ok()) {
114  Table* t = reinterpret_cast<TableAndFile*>(cache_->Value(handle))->table;
115  s = t->InternalGet(options, k, arg, saver);
116  cache_->Release(handle);
117  }
118  return s;
119 }
120 
121 void TableCache::Evict(uint64_t file_number) {
122  char buf[sizeof(file_number)];
123  EncodeFixed64(buf, file_number);
124  cache_->Erase(Slice(buf, sizeof(buf)));
125 }
126 
127 } // namespace leveldb
virtual Handle * Insert(const Slice &key, void *value, size_t charge, void(*deleter)(const Slice &key, void *value))=0
Iterator * NewIterator(const ReadOptions &) const
Definition: table.cc:220
static void DeleteEntry(const Slice &key, void *value)
Definition: table_cache.cc:19
virtual void Release(Handle *handle)=0
virtual void * Value(Handle *handle)=0
static Status Open(const Options &options, RandomAccessFile *file, uint64_t file_size, Table **table)
Definition: table.cc:38
const Options * options_
Definition: table_cache.h:53
virtual Handle * Lookup(const Slice &key)=0
std::string TableFileName(const std::string &name, uint64_t number)
Definition: filename.cc:32
void Evict(uint64_t file_number)
Definition: table_cache.cc:121
virtual Status NewRandomAccessFile(const std::string &fname, RandomAccessFile **result)=0
void EncodeFixed64(char *buf, uint64_t value)
Definition: coding.cc:20
Status InternalGet(const ReadOptions &, const Slice &key, void *arg, void(*handle_result)(void *arg, const Slice &k, const Slice &v))
Definition: table.cc:226
static Status OK()
Definition: status.h:32
Status FindTable(uint64_t file_number, uint64_t file_size, Cache::Handle **)
Definition: table_cache.cc:45
Iterator * NewErrorIterator(const Status &status)
Definition: iterator.cc:63
static char dbname[200]
Definition: c_test.c:15
static void UnrefEntry(void *arg1, void *arg2)
Definition: table_cache.cc:26
std::string SSTTableFileName(const std::string &name, uint64_t number)
Definition: filename.cc:37
Iterator * NewIterator(const ReadOptions &options, uint64_t file_number, uint64_t file_size, Table **tableptr=NULL)
Definition: table_cache.cc:82
Cache * NewLRUCache(size_t capacity)
Definition: cache.cc:401
bool ok() const
Definition: status.h:52
void RegisterCleanup(CleanupFunction function, void *arg1, void *arg2)
Definition: iterator.cc:26
Status Get(const ReadOptions &options, uint64_t file_number, uint64_t file_size, const Slice &k, void *arg, void(*handle_result)(void *, const Slice &, const Slice &))
Definition: table_cache.cc:105
virtual void Erase(const Slice &key)=0
const std::string dbname_
Definition: table_cache.h:52
RandomAccessFile * file
Definition: table_cache.cc:15
TableCache(const std::string &dbname, const Options *options, int entries)
Definition: table_cache.cc:32