Repository navigation
Expand file tree
/
Copy pathstore_cache.cc
More file actions
110 lines (94 loc) · 3.65 KB
/
Copy pathstore_cache.cc
File metadata and controls
110 lines (94 loc) · 3.65 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#include "db/store_cache.h"
#include "db/filename.h"
#include "util/coding.h"
namespace stackfiledb {
static void DeleteEntry(const Slice& key, void* value) {
StoreAccessFile* tf = reinterpret_cast<StoreAccessFile*>(value);
delete tf->file;
delete tf;
}
StoreFileCache::StoreFileCache(const std::string& dbname, const Options& options,
int entries)
: env_(options.env),
dbname_(dbname),
options_(options),
cache_(NewLRUCache(entries)) {}
StoreFileCache::~StoreFileCache() { delete cache_; }
void StoreFileCache::Release(Cache::Handle* handle) {
if(handle != nullptr)
cache_->Release(handle);
}
bool StoreFileCache::IsExists(uint32_t bucketId, uint32_t file_number) {
char buf[8];
EncodeFixed32(buf, bucketId);
EncodeFixed32(buf + 4, file_number);
Slice key(buf, sizeof(buf));
Cache::Handle* handle = cache_->Lookup(key);
if (handle == nullptr) return false;
cache_->Release(handle);
return true;
}
Status StoreFileCache::Get(uint32_t bucketId, uint32_t file_number, StoreAccessFile** accessfile) {
*accessfile = nullptr;
char buf[8];
EncodeFixed32(buf, bucketId);
EncodeFixed32(buf + 4, file_number);
Status status;
Slice key(buf, sizeof(buf));
Cache::Handle* handle = cache_->Lookup(key);
if (handle == nullptr) {
std::string fname = StoreFileName(dbname_, bucketId, file_number);
RandomAccessFile* file = nullptr;
//here need lock to prevent other compact and delete this file
status = env_->NewRandomAccessFile(fname, &file);
if (status.ok()) {
}
if (!status.ok()) {
if(file != nullptr) delete file;
// We do not cache error results so that if the error is transient,
// or somebody repairs the file, we recover automatically.
}
else {
StoreAccessFile* tf = new StoreAccessFile();
handle = cache_->Insert(key, tf, 1, &DeleteEntry);
tf->file = file;
tf->handle = handle;
}
}
if (status.ok()) {
*accessfile = reinterpret_cast<StoreAccessFile*>(cache_->Value(handle));
}
return status;
}
Status StoreFileCache::Add(uint32_t bucketId, uint32_t file_number, Cache::Handle** handle) {
*handle = nullptr;
char buf[8];
EncodeFixed32(buf, bucketId);
EncodeFixed32(buf + 4, file_number);
Status status;
Slice key(buf, sizeof(buf));
Cache::Handle* h = cache_->Lookup(key);
if (h == nullptr) {
std::string fname = StoreFileName(dbname_, bucketId, file_number);
RandomAccessFile* file = nullptr;
status = env_->NewRandomAccessFile(fname, &file, false);
if (!status.ok()) {
delete file;
// We do not cache error results so that if the error is transient,
// or somebody repairs the file, we recover automatically.
}
else {
StoreAccessFile* tf = new StoreAccessFile();
*handle = cache_->Insert(key, tf, 1, &DeleteEntry);
tf->file = file;
tf->handle = *handle;
//here handle ref == 2
}
}
else {
cache_->Release(h);
status = Status::AlreadyExists("New Store file AlreadyExists");
}
return status;
}
} // namespace stackfiledb