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
115
116
117
118
119
120
121
122
|
#pragma once
#include "erebos/storage.h"
#include <future>
#include <unordered_map>
#include <unordered_set>
namespace fs = std::filesystem;
using std::optional;
using std::shared_future;
using std::shared_ptr;
using std::unique_ptr;
using std::unordered_map;
using std::unordered_set;
using std::variant;
using std::vector;
namespace erebos {
class StorageBackend
{
public:
StorageBackend() = default;
virtual ~StorageBackend() = default;
virtual bool contains(const Digest &) const = 0;
virtual optional<vector<uint8_t>> loadBytes(const Digest &) const = 0;
virtual void storeBytes(const Digest &, const vector<uint8_t> &) = 0;
virtual optional<vector<uint8_t>> loadKey(const Digest &) const = 0;
virtual void storeKey(const Digest &, const vector<uint8_t> &) = 0;
};
class FilesystemStorage : public StorageBackend
{
public:
FilesystemStorage(const fs::path &);
virtual ~FilesystemStorage() = default;
virtual bool contains(const Digest &) const override;
virtual optional<vector<uint8_t>> loadBytes(const Digest &) const override;
virtual void storeBytes(const Digest &, const vector<uint8_t> &) override;
virtual optional<vector<uint8_t>> loadKey(const Digest &) const override;
virtual void storeKey(const Digest &, const vector<uint8_t> &) override;
private:
static constexpr size_t CHUNK = 16384;
fs::path objectPath(const Digest &) const;
fs::path keyPath(const Digest &) const;
fs::path root;
};
class MemoryStorage : public StorageBackend
{
public:
MemoryStorage() = default;
virtual ~MemoryStorage() = default;
virtual bool contains(const Digest &) const override;
virtual optional<vector<uint8_t>> loadBytes(const Digest &) const override;
virtual void storeBytes(const Digest &, const vector<uint8_t> &) override;
virtual optional<vector<uint8_t>> loadKey(const Digest &) const override;
virtual void storeKey(const Digest &, const vector<uint8_t> &) override;
private:
unordered_map<Digest, vector<uint8_t>> storage;
unordered_map<Digest, vector<uint8_t>> keys;
};
class ChainStorage : public StorageBackend
{
public:
ChainStorage(shared_ptr<StorageBackend> storage):
ChainStorage(std::move(storage), nullptr) {}
ChainStorage(shared_ptr<StorageBackend> storage, unique_ptr<ChainStorage> parent):
storage(std::move(storage)), parent(std::move(parent)) {}
virtual ~ChainStorage() = default;
virtual bool contains(const Digest &) const override;
virtual optional<vector<uint8_t>> loadBytes(const Digest &) const override;
virtual void storeBytes(const Digest &, const vector<uint8_t> &) override;
virtual optional<vector<uint8_t>> loadKey(const Digest &) const override;
virtual void storeKey(const Digest &, const vector<uint8_t> &) override;
private:
shared_ptr<StorageBackend> storage;
unique_ptr<ChainStorage> parent;
};
struct Storage::Priv
{
shared_ptr<StorageBackend> backend;
Digest storeBytes(const vector<uint8_t> &) const;
optional<vector<uint8_t>> loadBytes(const Digest & digest) const;
template<class S>
optional<Digest> copy(const typename S::Ref &, vector<Digest> *) const;
template<class S>
optional<Digest> copy(const ObjectT<S> &, vector<Digest> *) const;
};
struct Ref::Priv
{
const unique_ptr<PartialStorage> storage;
const Digest digest;
};
vector<Stored<Object>> collectStoredObjects(const Stored<Object> &);
}
|