Merge #11345: [tests] Check connectivity before sending in assumevalid.py
[bitcoinplatinum.git] / src / leveldb / db / table_cache.cc
blobe3d82cd3ea2d89d11ca6ca06b5ce7d5b7068a358
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"
12 namespace leveldb {
14 struct TableAndFile {
15 RandomAccessFile* file;
16 Table* table;
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;
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);
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)) {
41 TableCache::~TableCache() {
42 delete cache_;
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();
63 if (s.ok()) {
64 s = Table::Open(*options_, file, file_size, &table);
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);
79 return s;
82 Iterator* TableCache::NewIterator(const ReadOptions& options,
83 uint64_t file_number,
84 uint64_t file_size,
85 Table** tableptr) {
86 if (tableptr != NULL) {
87 *tableptr = NULL;
90 Cache::Handle* handle = NULL;
91 Status s = FindTable(file_number, file_size, &handle);
92 if (!s.ok()) {
93 return NewErrorIterator(s);
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;
102 return result;
105 Status TableCache::Get(const ReadOptions& options,
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);
118 return s;
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)));
127 } // namespace leveldb