}
void
-AtomicFile::write(const util::Blob& data)
+AtomicFile::write(nonstd::span<const uint8_t> data)
{
if (fwrite(data.data(), data.size(), 1, m_stream) != 1) {
throw core::Error(
#pragma once
-#include <util/types.hpp>
+#include <third_party/nonstd/span.hpp>
#include <cstdint>
#include <cstdio>
FILE* stream();
void write(const std::string& data);
- void write(const util::Blob& data);
+ void write(nonstd::span<const uint8_t> data);
// Close the temporary file and rename it to the destination file. Note: The
// destructor will not do this automatically to avoid half-written data in the
m_secondary_storages.end(),
[](const auto& entry) { return !entry->config.read_only; });
if (should_put_in_secondary_storage) {
- const auto value = util::read_file<util::Blob>(*path);
+ const auto value = util::read_file<std::vector<uint8_t>>(*path);
if (!value) {
LOG("Failed to read {}: {}", *path, value.error());
return path; // Don't indicate failure since primary storage was OK.
m_secondary_storages.end(),
[](const auto& entry) { return !entry->config.read_only; });
if (should_put_in_secondary_storage) {
- const auto value = util::read_file<util::Blob>(*path);
+ const auto value = util::read_file<std::vector<uint8_t>>(*path);
if (!value) {
LOG("Failed to read {}: {}", *path, value.error());
return true; // Don't indicate failure since primary storage was OK.
}
}
-std::optional<util::Blob>
+std::optional<std::vector<uint8_t>>
Storage::get_from_secondary_storage(const Digest& key)
{
MTR_SCOPE("secondary_storage", "get");
void
Storage::put_in_secondary_storage(const Digest& key,
- const util::Blob& value,
+ const std::vector<uint8_t>& value,
bool only_if_missing)
{
MTR_SCOPE("secondary_storage", "put");
#include <storage/primary/PrimaryStorage.hpp>
#include <storage/secondary/SecondaryStorage.hpp>
#include <storage/types.hpp>
-#include <util/types.hpp>
#include <functional>
#include <memory>
const Digest& key,
std::string_view operation_description,
const bool for_writing);
- std::optional<util::Blob> get_from_secondary_storage(const Digest& key);
+
+ std::optional<std::vector<uint8_t>>
+ get_from_secondary_storage(const Digest& key);
void put_in_secondary_storage(const Digest& key,
- const util::Blob& value,
+ const std::vector<uint8_t>& value,
bool only_if_missing);
void remove_from_secondary_storage(const Digest& key);
public:
FileStorageBackend(const Params& params);
- nonstd::expected<std::optional<util::Blob>, Failure>
+ nonstd::expected<std::optional<std::vector<uint8_t>>, Failure>
get(const Digest& key) override;
nonstd::expected<bool, Failure> put(const Digest& key,
- const util::Blob& value,
+ const std::vector<uint8_t>& value,
bool only_if_missing) override;
nonstd::expected<bool, Failure> remove(const Digest& key) override;
}
}
-nonstd::expected<std::optional<util::Blob>, SecondaryStorage::Backend::Failure>
+nonstd::expected<std::optional<std::vector<uint8_t>>,
+ SecondaryStorage::Backend::Failure>
FileStorageBackend::get(const Digest& key)
{
const auto path = get_entry_path(key);
util::set_timestamps(path);
}
- auto value = util::read_file<util::Blob>(path);
+ auto value = util::read_file<std::vector<uint8_t>>(path);
if (!value) {
LOG("Failed to read {}: {}", path, value.error());
return nonstd::make_unexpected(Failure::error);
nonstd::expected<bool, SecondaryStorage::Backend::Failure>
FileStorageBackend::put(const Digest& key,
- const util::Blob& value,
+ const std::vector<uint8_t>& value,
const bool only_if_missing)
{
const auto path = get_entry_path(key);
public:
HttpStorageBackend(const Params& params);
- nonstd::expected<std::optional<util::Blob>, Failure>
+ nonstd::expected<std::optional<std::vector<uint8_t>>, Failure>
get(const Digest& key) override;
nonstd::expected<bool, Failure> put(const Digest& key,
- const util::Blob& value,
+ const std::vector<uint8_t>& value,
bool only_if_missing) override;
nonstd::expected<bool, Failure> remove(const Digest& key) override;
m_http_client.set_write_timeout(operation_timeout);
}
-nonstd::expected<std::optional<util::Blob>, SecondaryStorage::Backend::Failure>
+nonstd::expected<std::optional<std::vector<uint8_t>>,
+ SecondaryStorage::Backend::Failure>
HttpStorageBackend::get(const Digest& key)
{
const auto url_path = get_entry_path(key);
return std::nullopt;
}
- return util::Blob(result->body.begin(), result->body.end());
+ return std::vector<uint8_t>(result->body.begin(), result->body.end());
}
nonstd::expected<bool, SecondaryStorage::Backend::Failure>
HttpStorageBackend::put(const Digest& key,
- const util::Blob& value,
+ const std::vector<uint8_t>& value,
const bool only_if_missing)
{
const auto url_path = get_entry_path(key);
public:
RedisStorageBackend(const SecondaryStorage::Backend::Params& params);
- nonstd::expected<std::optional<util::Blob>, Failure>
+ nonstd::expected<std::optional<std::vector<uint8_t>>, Failure>
get(const Digest& key) override;
nonstd::expected<bool, Failure> put(const Digest& key,
- const util::Blob& value,
+ const std::vector<uint8_t>& value,
bool only_if_missing) override;
nonstd::expected<bool, Failure> remove(const Digest& key) override;
#endif
}
-nonstd::expected<std::optional<util::Blob>, SecondaryStorage::Backend::Failure>
+nonstd::expected<std::optional<std::vector<uint8_t>>,
+ SecondaryStorage::Backend::Failure>
RedisStorageBackend::get(const Digest& key)
{
const auto key_string = get_key_string(key);
if (!reply) {
return nonstd::make_unexpected(reply.error());
} else if ((*reply)->type == REDIS_REPLY_STRING) {
- return util::Blob((*reply)->str, (*reply)->str + (*reply)->len);
+ return std::vector<uint8_t>((*reply)->str, (*reply)->str + (*reply)->len);
} else if ((*reply)->type == REDIS_REPLY_NIL) {
return std::nullopt;
} else {
nonstd::expected<bool, SecondaryStorage::Backend::Failure>
RedisStorageBackend::put(const Digest& key,
- const util::Blob& value,
+ const std::vector<uint8_t>& value,
bool only_if_missing)
{
const auto key_string = get_key_string(key);
#pragma once
#include <storage/types.hpp>
-#include <util/types.hpp>
#include <third_party/nonstd/expected.hpp>
#include <third_party/url.hpp>
// Get the value associated with `key`. Returns the value on success or
// std::nullopt if the entry is not present.
- virtual nonstd::expected<std::optional<util::Blob>, Failure>
+ virtual nonstd::expected<std::optional<std::vector<uint8_t>>, Failure>
get(const Digest& key) = 0;
// Put `value` associated to `key` in the storage. A true `only_if_missing`
// Returns true if the entry was stored, otherwise false.
virtual nonstd::expected<bool, Failure>
put(const Digest& key,
- const util::Blob& value,
+ const std::vector<uint8_t>& value,
bool only_if_missing = false) = 0;
// Remove `key` and its associated value. Returns true if the entry was
template nonstd::expected<std::string, std::string>
read_file(const std::string& path, size_t size_hint);
-template nonstd::expected<util::Blob, std::string>
+template nonstd::expected<std::vector<uint8_t>, std::string>
read_file(const std::string& path, size_t size_hint);
void
nonstd::expected<void, std::string> read_fd(int fd, DataReceiver data_receiver);
// Return data from `path`, where `T` is `std::string` for text data and
-// `util::Blob` for binary data. If `T` is `std::string` and the content starts
-// with a UTF-16 little-endian BOM on Windows then it will be converted to
-// UTF-8. If `size_hint` is not 0 then it is assumed that `path` has this size
-// (this saves system calls).
+// `std::vector<uint8_t>` for binary data. If `T` is `std::string` and the
+// content starts with a UTF-16 little-endian BOM on Windows then it will be
+// converted to UTF-8. If `size_hint` is not 0 then it is assumed that `path`
+// has this size (this saves system calls).
template<typename T>
nonstd::expected<T, std::string> read_file(const std::string& path,
size_t size_hint = 0);
namespace util {
-using Blob = std::vector<uint8_t>;
using DataReceiver = std::function<void(const void* data, size_t size)>;
} // namespace util
AtomicFile atomic_file("test", AtomicFile::Mode::text);
atomic_file.write("h");
- atomic_file.write(util::Blob{0x65, 0x6c});
+ atomic_file.write(std::vector<uint8_t>{0x65, 0x6c});
fputs("lo", atomic_file.stream());
atomic_file.commit();
CHECK(*util::read_file<std::string>("test") == "hello");
// Newline handling
REQUIRE(util::write_file("test", "foo\r\nbar\n"));
- auto bin_data = util::read_file<util::Blob>("test");
+ auto bin_data = util::read_file<std::vector<uint8_t>>("test");
REQUIRE(bin_data);
#ifdef _WIN32
const std::string expected_bin_data = "foo\r\r\nbar\r\n";
const std::string expected_bin_data = "foo\r\nbar\n";
#endif
CHECK(*bin_data
- == util::Blob(expected_bin_data.begin(), expected_bin_data.end()));
+ == std::vector<uint8_t>(expected_bin_data.begin(),
+ expected_bin_data.end()));
REQUIRE(util::write_file("size_hint_test", std::string(8192, '\0')));
data = util::read_file<std::string>("size_hint_test", 8191 /*size_hint*/);
{
TestContext test_context;
- util::Blob expected;
+ std::vector<uint8_t> expected;
for (size_t i = 0; i < 512; ++i) {
expected.push_back((32 + i) % 256);
}
CHECK(util::write_file("test", expected));
- auto actual = util::read_file<util::Blob>("test");
+ auto actual = util::read_file<std::vector<uint8_t>>("test");
REQUIRE(actual);
CHECK(*actual == expected);
- REQUIRE(util::write_file("size_hint_test", util::Blob(8192, 0)));
- auto data = util::read_file<util::Blob>("size_hint_test", 8191 /*size_hint*/);
+ REQUIRE(util::write_file("size_hint_test", std::vector<uint8_t>(8192, 0)));
+ auto data =
+ util::read_file<std::vector<uint8_t>>("size_hint_test", 8191 /*size_hint*/);
REQUIRE(data);
CHECK(data->size() == 8192);
- data = util::read_file<util::Blob>("size_hint_test", 8193 /*size_hint*/);
+ data =
+ util::read_file<std::vector<uint8_t>>("size_hint_test", 8193 /*size_hint*/);
REQUIRE(data);
CHECK(data->size() == 8192);
}