blob: 40b24f2ec2684776ef7c462924eb4938e405ab6d (
plain) (
blame)
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
111
112
113
114
|
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#include "attributedisklayout.h"
#include "attribute_directory.h"
#include <vespa/vespalib/io/fileutil.h>
#include <cassert>
#include <filesystem>
namespace proton {
AttributeDiskLayout::AttributeDiskLayout(const vespalib::string &baseDir, PrivateConstructorTag)
: _baseDir(baseDir),
_mutex(),
_dirs()
{
std::filesystem::create_directory(std::filesystem::path(_baseDir));
vespalib::File::sync(vespalib::dirname(_baseDir));
}
AttributeDiskLayout::~AttributeDiskLayout() = default;
std::vector<vespalib::string>
AttributeDiskLayout::listAttributes()
{
std::vector<vespalib::string> attributes;
std::shared_lock<std::shared_mutex> guard(_mutex);
for (const auto &dir : _dirs) {
attributes.emplace_back(dir.first);
}
return attributes;
}
void
AttributeDiskLayout::scanDir()
{
std::filesystem::directory_iterator dir_scan{std::filesystem::path(_baseDir)};
for (auto& entry : dir_scan) {
if (entry.is_directory()) {
createAttributeDir(entry.path().filename().string());
}
}
}
std::shared_ptr<AttributeDirectory>
AttributeDiskLayout::getAttributeDir(const vespalib::string &name)
{
std::shared_lock<std::shared_mutex> guard(_mutex);
auto itr = _dirs.find(name);
if (itr == _dirs.end()) {
return std::shared_ptr<AttributeDirectory>();
} else {
return itr->second;
}
}
std::shared_ptr<AttributeDirectory>
AttributeDiskLayout::createAttributeDir(const vespalib::string &name)
{
std::lock_guard<std::shared_mutex> guard(_mutex);
auto itr = _dirs.find(name);
if (itr == _dirs.end()) {
auto dir = std::make_shared<AttributeDirectory>(shared_from_this(), name);
auto insres = _dirs.insert(std::make_pair(name, dir));
assert(insres.second);
return dir;
} else {
return itr->second;
}
}
void
AttributeDiskLayout::removeAttributeDir(const vespalib::string &name, search::SerialNum serialNum)
{
auto dir = getAttributeDir(name);
if (dir) {
auto writer = dir->getWriter();
if (writer) {
writer->invalidateOldSnapshots(serialNum);
writer->removeInvalidSnapshots();
if (writer->removeDiskDir()) {
std::lock_guard<std::shared_mutex> guard(_mutex);
auto itr = _dirs.find(name);
assert(itr != _dirs.end());
assert(dir.get() == itr->second.get());
_dirs.erase(itr);
writer->detach();
}
} else {
std::lock_guard<std::shared_mutex> guard(_mutex);
auto itr = _dirs.find(name);
if (itr != _dirs.end()) {
assert(dir.get() != itr->second.get());
}
}
}
}
std::shared_ptr<AttributeDiskLayout>
AttributeDiskLayout::create(const vespalib::string &baseDir)
{
auto diskLayout = std::make_shared<AttributeDiskLayout>(baseDir, PrivateConstructorTag());
diskLayout->scanDir();
return diskLayout;
}
std::shared_ptr<AttributeDiskLayout>
AttributeDiskLayout::createSimple(const vespalib::string &baseDir)
{
auto diskLayout = std::make_shared<AttributeDiskLayout>(baseDir, PrivateConstructorTag());
return diskLayout;
}
} // namespace proton
|