Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
110 changes: 110 additions & 0 deletions include/pain/base/object_id.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
#pragma once

#include <pain/base/uuid.h>
#include <string>
#include <fmt/format.h>
#include <boost/assert.hpp>

namespace pain {

class ObjectId {
public:
ObjectId(uint32_t partition_id, UUID uuid) : _reserved(0), _partition_id(partition_id), _uuid(uuid) {}

uint32_t partition_id() const {
return _partition_id;
}

UUID uuid() const {
return _uuid;
}

bool operator==(const ObjectId& other) const {
return _partition_id == other._partition_id && _uuid == other._uuid;
}

bool operator!=(const ObjectId& other) const {
return !(*this == other);
}

bool operator<(const ObjectId& other) const {
return _partition_id < other._partition_id || (_partition_id == other._partition_id && _uuid < other._uuid);
}

bool operator>(const ObjectId& other) const {
return other < *this;
}

bool operator<=(const ObjectId& other) const {
return !(*this > other);
}

bool operator>=(const ObjectId& other) const {
return !(*this < other);
}

std::string to_string() const {
return fmt::format("{}-{}", _partition_id, _uuid.str());
}

static std::optional<ObjectId> from_str(std::string_view str) {
auto pos = str.find('-');
if (pos == std::string::npos) {
return std::nullopt;
}
auto [partition_id_str, uuid_str] = split(str);
if (partition_id_str.empty() || uuid_str.empty()) {
return std::nullopt;
}
uint32_t pid = 0;
try {
pid = std::stoull(partition_id_str.data());
} catch (const std::exception& e) {
return std::nullopt;
}
auto uuid = UUID::from_str(uuid_str);
if (!uuid) {
return std::nullopt;
}
return ObjectId(pid, uuid.value());
}

static ObjectId from_str_or_die(std::string_view str) {
auto [partition_id_str, uuid_str] = split(str);
if (partition_id_str.empty() || uuid_str.empty()) {
BOOST_ASSERT_MSG(false, fmt::format("Invalid ObjectId string: {}", str).c_str());
}
uint32_t pid = 0;
try {
pid = std::stoull(partition_id_str.data());
} catch (const std::exception& e) {
BOOST_ASSERT_MSG(false, fmt::format("Invalid ObjectId string: {}", str).c_str());
}

auto uuid = UUID::from_str_or_die(uuid_str);
return ObjectId(pid, uuid);
}

private:
static std::pair<std::string_view, std::string_view> split(std::string_view str) {
auto pos = str.find('-');
BOOST_ASSERT_MSG(pos != std::string::npos, "Invalid ObjectId string");
return {str.substr(0, pos), str.substr(pos + 1)};
}

private:
uint32_t _reserved;
uint32_t _partition_id;
UUID _uuid;
};

} // namespace pain

namespace std {
template <>
struct hash<pain::ObjectId> {
std::size_t operator()(const pain::ObjectId& obj) const {
return std::hash<uint64_t>()(obj.partition_id()) ^ std::hash<pain::UUID>()(obj.uuid());
}
};
} // namespace std
13 changes: 8 additions & 5 deletions include/pain/base/uuid.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
#include <uuid_v4/uuid_v4.h>
#include <functional>
#include <optional>
#include <fmt/format.h>
#include <boost/assert.hpp>

namespace pain {

Expand All @@ -22,7 +24,7 @@ class UUID : public UUIDv4::UUID {
return *reinterpret_cast<const uint64_t*>(data + 8); // NOLINT
}

static bool valid(const std::string& uuid) {
static bool valid(std::string_view uuid) {
constexpr size_t guid_length = 36U;
if (uuid.length() != guid_length) {
return false;
Expand All @@ -45,17 +47,18 @@ class UUID : public UUIDv4::UUID {
return true;
}

static std::optional<UUID> from_str(const std::string& str) {
static std::optional<UUID> from_str(std::string_view str) {
if (!valid(str)) {
return std::nullopt;
}

auto uuid = UUIDv4::UUID::fromStrFactory(str);
auto uuid = UUIDv4::UUID::fromStrFactory(str.data());
return UUID(uuid);
}

static UUID from_str_or_die(const std::string& str) {
auto uuid = UUIDv4::UUID::fromStrFactory(str);
static UUID from_str_or_die(std::string_view str) {
BOOST_ASSERT_MSG(valid(str), fmt::format("Invalid UUID string: {}", str).c_str());
auto uuid = UUIDv4::UUID::fromStrFactory(str.data());
return UUID(uuid);
}

Expand Down
6 changes: 6 additions & 0 deletions protocols/pain/proto/common.proto
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ message UUID {
uint64 high = 2;
}

message ObjectId {
uint32 reserved = 1;
uint32 partition_id = 2;
UUID uuid = 3;
}

message Pair {
string key = 1;
string value = 2;
Expand Down
Loading