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.
5 #include "db/table_cache.h"
7 #include "db/filename.h"
8 #include "leveldb/env.h"
9 #include "leveldb/table.h"
10 #include "util/coding.h"
15 RandomAccessFile* file;
19 static void DeleteEntry(const Slice& key, void* value) {
20 TableAndFile* tf = reinterpret_cast<TableAndFile*>(value);
26 static void UnrefEntry(void* arg1, void* arg2) {
27 Cache* cache = reinterpret_cast<Cache*>(arg1);
28 Cache::Handle* h = reinterpret_cast<Cache::Handle*>(arg2);
32 TableCache::TableCache(const std::string& dbname,
33 const Options* options,
38 cache_(NewLRUCache(entries)) {
41 TableCache::~TableCache() {
45 Status TableCache::FindTable(uint64_t file_number, uint64_t file_size,
46 Cache::Handle** handle) {
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;
56 s = env_->NewRandomAccessFile(fname, &file);
58 s = Table::Open(*options_, file, file_size, &table);
62 assert(table == NULL);
64 // We do not cache error results so that if the error is transient,
65 // or somebody repairs the file, we recover automatically.
67 TableAndFile* tf = new TableAndFile;
70 *handle = cache_->Insert(key, tf, 1, &DeleteEntry);
76 Iterator* TableCache::NewIterator(const ReadOptions& options,
80 if (tableptr != NULL) {
84 Cache::Handle* handle = NULL;
85 Status s = FindTable(file_number, file_size, &handle);
87 return NewErrorIterator(s);
90 Table* table = reinterpret_cast<TableAndFile*>(cache_->Value(handle))->table;
91 Iterator* result = table->NewIterator(options);
92 result->RegisterCleanup(&UnrefEntry, cache_, handle);
93 if (tableptr != NULL) {
99 Status TableCache::Get(const ReadOptions& options,
100 uint64_t file_number,
104 void (*saver)(void*, const Slice&, const Slice&)) {
105 Cache::Handle* handle = NULL;
106 Status s = FindTable(file_number, file_size, &handle);
108 Table* t = reinterpret_cast<TableAndFile*>(cache_->Value(handle))->table;
109 s = t->InternalGet(options, k, arg, saver);
110 cache_->Release(handle);
115 void TableCache::Evict(uint64_t file_number) {
116 char buf[sizeof(file_number)];
117 EncodeFixed64(buf, file_number);
118 cache_->Erase(Slice(buf, sizeof(buf)));
121 } // namespace leveldb