blob: 66500f4602208f9106b11151018c723b28088d88 [file] [log] [blame]
Kun Yi91beea62018-11-26 15:23:14 -08001#include "handler.hpp"
2
Kun Yi68c81142018-12-18 11:17:14 -08003#include <algorithm>
Kun Yid2d8cb62019-01-10 15:06:12 -08004#include <cstdint>
5#include <memory>
6#include <string>
7#include <vector>
8
9using std::size_t;
10using std::uint16_t;
11using std::uint32_t;
12using std::uint64_t;
13using std::uint8_t;
Kun Yi68c81142018-12-18 11:17:14 -080014
Kun Yi91beea62018-11-26 15:23:14 -080015namespace blobs
16{
17
Kun Yi38146a02018-12-18 21:54:26 -080018namespace internal
19{
20
Kun Yi64dc05c2018-12-19 13:19:03 -080021/**
22 * @brief: Get baseId from a blob id string
23 * @param blobId: Input blob id which is expected to only contain alphanumerical
24 * characters and '/'.
25 * @returns: the baseId containing the blobId, stripping all contents from the
26 * last '/'. If no '/' is present, an empty string is returned.
27 */
28static std::string getBaseFromId(const std::string& blobId)
Kun Yi38146a02018-12-18 21:54:26 -080029{
30 return blobId.substr(0, blobId.find_last_of('/') + 1);
31}
32
33} // namespace internal
34
Kun Yi68c81142018-12-18 11:17:14 -080035void BinaryStoreBlobHandler::addNewBinaryStore(
36 std::unique_ptr<binstore::BinaryStoreInterface> store)
37{
38 // TODO: this is a very rough measure to test the mock interface for now.
39 stores_[store->getBaseBlobId()] = std::move(store);
40}
41
Kun Yi91beea62018-11-26 15:23:14 -080042bool BinaryStoreBlobHandler::canHandleBlob(const std::string& path)
43{
Kun Yi64dc05c2018-12-19 13:19:03 -080044 auto base = internal::getBaseFromId(path);
45 if (base.empty() || base == path)
46 {
47 /* Operations on baseId itself or an empty base is not allowed */
48 return false;
49 }
50
Kun Yi68c81142018-12-18 11:17:14 -080051 return std::any_of(stores_.begin(), stores_.end(),
52 [&](const auto& baseStorePair) {
Kun Yi64dc05c2018-12-19 13:19:03 -080053 return base == baseStorePair.second->getBaseBlobId();
Kun Yi68c81142018-12-18 11:17:14 -080054 });
Kun Yi91beea62018-11-26 15:23:14 -080055}
56
57std::vector<std::string> BinaryStoreBlobHandler::getBlobIds()
58{
Kun Yi91beea62018-11-26 15:23:14 -080059 std::vector<std::string> result;
Kun Yi68c81142018-12-18 11:17:14 -080060
61 for (const auto& baseStorePair : stores_)
62 {
63 const auto& ids = baseStorePair.second->getBlobIds();
64 result.insert(result.end(), ids.begin(), ids.end());
65 }
66
Kun Yi91beea62018-11-26 15:23:14 -080067 return result;
68}
69
70bool BinaryStoreBlobHandler::deleteBlob(const std::string& path)
71{
Kun Yic0adbc32018-12-18 22:35:29 -080072 auto it = stores_.find(internal::getBaseFromId(path));
73 if (it == stores_.end())
74 {
75 return false;
76 }
77
78 return it->second->deleteBlob(path);
Kun Yi91beea62018-11-26 15:23:14 -080079}
80
81bool BinaryStoreBlobHandler::stat(const std::string& path,
82 struct BlobMeta* meta)
83{
Kun Yi1a25e0d2020-05-11 12:28:53 -070084 auto it = stores_.find(internal::getBaseFromId(path));
85 if (it == stores_.end())
86 {
87 return false;
88 }
89
90 return it->second->stat(meta);
Kun Yi91beea62018-11-26 15:23:14 -080091}
92
93bool BinaryStoreBlobHandler::open(uint16_t session, uint16_t flags,
94 const std::string& path)
95{
Kun Yi68c81142018-12-18 11:17:14 -080096 if (!canHandleBlob(path))
97 {
98 return false;
99 }
100
101 auto found = sessions_.find(session);
102 if (found != sessions_.end())
103 {
104 /* This session is already active */
105 return false;
106 }
107
Kun Yi38146a02018-12-18 21:54:26 -0800108 const auto& base = internal::getBaseFromId(path);
109
110 if (stores_.find(base) == stores_.end())
111 {
112 return false;
113 }
114
115 if (!stores_[base]->openOrCreateBlob(path, flags))
116 {
117 return false;
118 }
119
120 sessions_[session] = stores_[base].get();
121 return true;
Kun Yi91beea62018-11-26 15:23:14 -0800122}
123
124std::vector<uint8_t> BinaryStoreBlobHandler::read(uint16_t session,
125 uint32_t offset,
126 uint32_t requestedSize)
127{
Kun Yic0adbc32018-12-18 22:35:29 -0800128 auto it = sessions_.find(session);
129 if (it == sessions_.end())
130 {
131 return std::vector<uint8_t>();
132 }
133
134 return it->second->read(offset, requestedSize);
Kun Yi91beea62018-11-26 15:23:14 -0800135}
136
137bool BinaryStoreBlobHandler::write(uint16_t session, uint32_t offset,
138 const std::vector<uint8_t>& data)
139{
Kun Yic0adbc32018-12-18 22:35:29 -0800140 auto it = sessions_.find(session);
141 if (it == sessions_.end())
142 {
143 return false;
144 }
145
146 return it->second->write(offset, data);
Kun Yi91beea62018-11-26 15:23:14 -0800147}
148
149bool BinaryStoreBlobHandler::writeMeta(uint16_t session, uint32_t offset,
150 const std::vector<uint8_t>& data)
151{
152 /* Binary store handler doesn't support write meta */
153 return false;
154}
155
156bool BinaryStoreBlobHandler::commit(uint16_t session,
157 const std::vector<uint8_t>& data)
158{
Kun Yid297c9f2019-01-09 13:52:30 -0800159 auto it = sessions_.find(session);
160 if (it == sessions_.end())
161 {
162 return false;
163 }
164
165 return it->second->commit();
Kun Yi91beea62018-11-26 15:23:14 -0800166}
167
168bool BinaryStoreBlobHandler::close(uint16_t session)
169{
Kun Yic0adbc32018-12-18 22:35:29 -0800170 auto it = sessions_.find(session);
171 if (it == sessions_.end())
172 {
173 return false;
174 }
175
176 if (!it->second->close())
177 {
178 return false;
179 }
180
181 sessions_.erase(session);
182 return true;
Kun Yi91beea62018-11-26 15:23:14 -0800183}
184
185bool BinaryStoreBlobHandler::stat(uint16_t session, struct BlobMeta* meta)
186{
Kun Yi1a25e0d2020-05-11 12:28:53 -0700187 auto it = sessions_.find(session);
188 if (it == sessions_.end())
189 {
190 return false;
191 }
192
193 return it->second->stat(meta);
Kun Yi91beea62018-11-26 15:23:14 -0800194}
195
196bool BinaryStoreBlobHandler::expire(uint16_t session)
197{
Kun Yi44d9e602019-11-21 18:23:10 -0800198 return close(session);
Kun Yi91beea62018-11-26 15:23:14 -0800199}
200
201} // namespace blobs