Skip to content

Commit b435dc9

Browse files
committed
fix: review comments
1 parent 1274056 commit b435dc9

File tree

3 files changed

+94
-88
lines changed

3 files changed

+94
-88
lines changed

src/iceberg/util/uuid.cc

Lines changed: 78 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -32,77 +32,6 @@
3232

3333
namespace iceberg {
3434

35-
Uuid::Uuid(std::array<uint8_t, kUuidSize> data) : data_(std::move(data)) {}
36-
37-
Uuid Uuid::GenerateV4() {
38-
static std::random_device rd;
39-
static std::mt19937 gen(rd());
40-
static std::uniform_int_distribution<uint64_t> distrib(
41-
std::numeric_limits<uint64_t>::min(), std::numeric_limits<uint64_t>::max());
42-
std::array<uint8_t, 16> uuid;
43-
44-
// Generate two random 64-bit integers
45-
uint64_t high_bits = distrib(gen);
46-
uint64_t low_bits = distrib(gen);
47-
48-
// Combine them into a uint128_t
49-
uint128_t random_128_bit_number = (static_cast<uint128_t>(high_bits) << 64) | low_bits;
50-
51-
// Copy the bytes into the uuid array
52-
std::memcpy(uuid.data(), &random_128_bit_number, 16);
53-
54-
// Set magic numbers for a "version 4" (pseudorandom) UUID and variant,
55-
// see https://datatracker.ietf.org/doc/html/rfc9562#name-uuid-version-4
56-
uuid[6] = (uuid[6] & 0x0F) | 0x40;
57-
// Set variant field, top two bits are 1, 0
58-
uuid[8] = (uuid[8] & 0x3F) | 0x80;
59-
60-
return Uuid(std::move(uuid));
61-
}
62-
63-
Uuid Uuid::GenerateV7() {
64-
// Get the current time in milliseconds since the Unix epoch
65-
auto now = std::chrono::system_clock::now();
66-
auto duration_since_epoch = now.time_since_epoch();
67-
auto unix_ts_ms =
68-
std::chrono::duration_cast<std::chrono::milliseconds>(duration_since_epoch).count();
69-
70-
return GenerateV7(static_cast<uint64_t>(unix_ts_ms));
71-
}
72-
73-
Uuid Uuid::GenerateV7(uint64_t unix_ts_ms) {
74-
std::array<uint8_t, 16> uuid = {};
75-
76-
// Set the timestamp (in milliseconds since Unix epoch)
77-
uuid[0] = (unix_ts_ms >> 40) & 0xFF;
78-
uuid[1] = (unix_ts_ms >> 32) & 0xFF;
79-
uuid[2] = (unix_ts_ms >> 24) & 0xFF;
80-
uuid[3] = (unix_ts_ms >> 16) & 0xFF;
81-
uuid[4] = (unix_ts_ms >> 8) & 0xFF;
82-
uuid[5] = unix_ts_ms & 0xFF;
83-
84-
// Generate random bytes for the remaining fields
85-
static std::random_device rd;
86-
static std::mt19937 gen(rd());
87-
static std::uniform_int_distribution<uint16_t> distrib(
88-
std::numeric_limits<uint16_t>::min(), std::numeric_limits<uint16_t>::max());
89-
90-
// Note: uint8_t is invalid for uniform_int_distribution on Windows
91-
for (size_t i = 6; i < 16; i += 2) {
92-
auto rand = static_cast<uint16_t>(distrib(gen));
93-
uuid[i] = (rand >> 8) & 0xFF;
94-
uuid[i + 1] = rand & 0xFF;
95-
}
96-
97-
// Set magic numbers for a "version 7" (pseudorandom) UUID and variant,
98-
// see https://www.rfc-editor.org/rfc/rfc9562#name-version-field
99-
uuid[6] = (uuid[6] & 0x0F) | 0x70;
100-
// set variant field, top two bits are 1, 0
101-
uuid[8] = (uuid[8] & 0x3F) | 0x80;
102-
103-
return Uuid(std::move(uuid));
104-
}
105-
10635
namespace {
10736

10837
constexpr std::array<uint8_t, 256> BuildHexTable() {
@@ -182,6 +111,77 @@ inline Result<Uuid> ParseHyphenated(std::string_view s) {
182111

183112
} // namespace
184113

114+
Uuid::Uuid(std::array<uint8_t, kLength> data) : data_(std::move(data)) {}
115+
116+
Uuid Uuid::GenerateV4() {
117+
static std::random_device rd;
118+
static std::mt19937 gen(rd());
119+
static std::uniform_int_distribution<uint64_t> distrib(
120+
std::numeric_limits<uint64_t>::min(), std::numeric_limits<uint64_t>::max());
121+
std::array<uint8_t, 16> uuid;
122+
123+
// Generate two random 64-bit integers
124+
uint64_t high_bits = distrib(gen);
125+
uint64_t low_bits = distrib(gen);
126+
127+
// Combine them into a uint128_t
128+
uint128_t random_128_bit_number = (static_cast<uint128_t>(high_bits) << 64) | low_bits;
129+
130+
// Copy the bytes into the uuid array
131+
std::memcpy(uuid.data(), &random_128_bit_number, 16);
132+
133+
// Set magic numbers for a "version 4" (pseudorandom) UUID and variant,
134+
// see https://datatracker.ietf.org/doc/html/rfc9562#name-uuid-version-4
135+
uuid[6] = (uuid[6] & 0x0F) | 0x40;
136+
// Set variant field, top two bits are 1, 0
137+
uuid[8] = (uuid[8] & 0x3F) | 0x80;
138+
139+
return Uuid(std::move(uuid));
140+
}
141+
142+
Uuid Uuid::GenerateV7() {
143+
// Get the current time in milliseconds since the Unix epoch
144+
auto now = std::chrono::system_clock::now();
145+
auto duration_since_epoch = now.time_since_epoch();
146+
auto unix_ts_ms =
147+
std::chrono::duration_cast<std::chrono::milliseconds>(duration_since_epoch).count();
148+
149+
return GenerateV7(static_cast<uint64_t>(unix_ts_ms));
150+
}
151+
152+
Uuid Uuid::GenerateV7(uint64_t unix_ts_ms) {
153+
std::array<uint8_t, 16> uuid = {};
154+
155+
// Set the timestamp (in milliseconds since Unix epoch)
156+
uuid[0] = (unix_ts_ms >> 40) & 0xFF;
157+
uuid[1] = (unix_ts_ms >> 32) & 0xFF;
158+
uuid[2] = (unix_ts_ms >> 24) & 0xFF;
159+
uuid[3] = (unix_ts_ms >> 16) & 0xFF;
160+
uuid[4] = (unix_ts_ms >> 8) & 0xFF;
161+
uuid[5] = unix_ts_ms & 0xFF;
162+
163+
// Generate random bytes for the remaining fields
164+
static std::random_device rd;
165+
static std::mt19937 gen(rd());
166+
static std::uniform_int_distribution<uint16_t> distrib(
167+
std::numeric_limits<uint16_t>::min(), std::numeric_limits<uint16_t>::max());
168+
169+
// Note: uint8_t is invalid for uniform_int_distribution on Windows
170+
for (size_t i = 6; i < 16; i += 2) {
171+
auto rand = static_cast<uint16_t>(distrib(gen));
172+
uuid[i] = (rand >> 8) & 0xFF;
173+
uuid[i + 1] = rand & 0xFF;
174+
}
175+
176+
// Set magic numbers for a "version 7" (pseudorandom) UUID and variant,
177+
// see https://www.rfc-editor.org/rfc/rfc9562#name-version-field
178+
uuid[6] = (uuid[6] & 0x0F) | 0x70;
179+
// set variant field, top two bits are 1, 0
180+
uuid[8] = (uuid[8] & 0x3F) | 0x80;
181+
182+
return Uuid(std::move(uuid));
183+
}
184+
185185
Result<Uuid> Uuid::FromString(std::string_view str) {
186186
if (str.size() == 32) {
187187
return ParseSimple(str);
@@ -193,23 +193,23 @@ Result<Uuid> Uuid::FromString(std::string_view str) {
193193
}
194194

195195
Result<Uuid> Uuid::FromBytes(std::span<const uint8_t> bytes) {
196-
if (bytes.size() != kUuidSize) [[unlikely]] {
197-
return InvalidArgument("UUID byte array must be exactly {} bytes, was {}", kUuidSize,
196+
if (bytes.size() != kLength) [[unlikely]] {
197+
return InvalidArgument("UUID byte array must be exactly {} bytes, was {}", kLength,
198198
bytes.size());
199199
}
200-
std::array<uint8_t, kUuidSize> data;
201-
std::memcpy(data.data(), bytes.data(), kUuidSize);
200+
std::array<uint8_t, kLength> data;
201+
std::memcpy(data.data(), bytes.data(), kLength);
202202
return Uuid(std::move(data));
203203
}
204204

205205
uint8_t Uuid::operator[](size_t index) const {
206-
ICEBERG_CHECK(index < kUuidSize, "UUID index out of range: {}", index);
206+
ICEBERG_CHECK(index < kLength, "UUID index out of range: {}", index);
207207
return data_[index];
208208
}
209209

210-
std::string Uuid::ToString() const {
211-
static const char* hex_chars = "0123456789abcdef";
210+
std::array<uint8_t, Uuid::kLength> Uuid::ToBigEndianBytes() const { return data_; }
212211

212+
std::string Uuid::ToString() const {
213213
return std::format(
214214
"{:02x}{:02x}{:02x}{:02x}-{:02x}{:02x}-{:02x}{:02x}-{:02x}{:02x}-{:02x}{:02x}{:02x}"
215215
"{:02x}{:02x}{:02x}",

src/iceberg/util/uuid.h

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,9 @@ namespace iceberg {
3535
class ICEBERG_EXPORT Uuid {
3636
public:
3737
Uuid() = delete;
38-
constexpr static size_t kUuidSize = 16;
38+
constexpr static size_t kLength = 16;
3939

40-
explicit Uuid(std::array<uint8_t, kUuidSize> data);
40+
explicit Uuid(std::array<uint8_t, kLength> data);
4141

4242
/// \brief Generate a random UUID (version 4).
4343
static Uuid GenerateV4();
@@ -61,10 +61,16 @@ class ICEBERG_EXPORT Uuid {
6161
/// \brief Create a UUID from a 16-byte array.
6262
static Result<Uuid> FromBytes(std::span<const uint8_t> bytes);
6363

64+
/// \brief Get the raw bytes of the UUID in big-endian order.
65+
std::array<uint8_t, kLength> ToBigEndianBytes() const;
66+
6467
/// \brief Get the raw bytes of the UUID.
6568
std::span<const uint8_t> bytes() const { return data_; }
6669

6770
/// \brief Access individual bytes of the UUID.
71+
/// \param index The index of the byte to access (0-15).
72+
/// \return The byte at the specified index.
73+
/// \throw IcebergError if index is out of bounds.
6874
uint8_t operator[](size_t index) const;
6975

7076
/// \brief Convert the UUID to a string in standard format.
@@ -75,7 +81,7 @@ class ICEBERG_EXPORT Uuid {
7581
}
7682

7783
private:
78-
std::array<uint8_t, kUuidSize> data_;
84+
std::array<uint8_t, kLength> data_;
7985
};
8086

8187
} // namespace iceberg

test/uuid_test.cc

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ namespace iceberg {
3030
TEST(UUIDUtilTest, GenerateV4) {
3131
auto uuid = Uuid::GenerateV4();
3232
// just ensure it runs and produces a value
33-
EXPECT_EQ(uuid.bytes().size(), Uuid::kUuidSize);
33+
EXPECT_EQ(uuid.bytes().size(), Uuid::kLength);
3434
// Version 4 UUIDs have the version number (4) in the 7th byte
3535
EXPECT_EQ((uuid[6] >> 4) & 0x0F, 4);
3636
// Variant is in the 9th byte, the two most significant bits should be 10
@@ -95,9 +95,9 @@ TEST(UUIDUtilTest, FromStringInvalid) {
9595
}
9696

9797
TEST(UUIDUtilTest, FromBytes) {
98-
std::array<uint8_t, Uuid::kUuidSize> bytes = {0x12, 0x3e, 0x45, 0x67, 0xe8, 0x9b,
99-
0x12, 0xd3, 0xa4, 0x56, 0x42, 0x66,
100-
0x14, 0x17, 0x40, 0x00};
98+
std::array<uint8_t, Uuid::kLength> bytes = {0x12, 0x3e, 0x45, 0x67, 0xe8, 0x9b,
99+
0x12, 0xd3, 0xa4, 0x56, 0x42, 0x66,
100+
0x14, 0x17, 0x40, 0x00};
101101
auto result = Uuid::FromBytes(bytes);
102102
EXPECT_THAT(result, IsOk());
103103
auto uuid = result.value();
@@ -106,9 +106,9 @@ TEST(UUIDUtilTest, FromBytes) {
106106
}
107107

108108
TEST(UUIDUtilTest, FromBytesInvalid) {
109-
std::array<uint8_t, Uuid::kUuidSize - 1> short_bytes = {0x12, 0x3e, 0x45, 0x67, 0xe8,
110-
0x9b, 0x12, 0xd3, 0xa4, 0x56,
111-
0x42, 0x66, 0x14, 0x17, 0x40};
109+
std::array<uint8_t, Uuid::kLength - 1> short_bytes = {0x12, 0x3e, 0x45, 0x67, 0xe8,
110+
0x9b, 0x12, 0xd3, 0xa4, 0x56,
111+
0x42, 0x66, 0x14, 0x17, 0x40};
112112
auto result = Uuid::FromBytes(short_bytes);
113113
EXPECT_THAT(result, IsError(ErrorKind::kInvalidArgument));
114114
EXPECT_THAT(result, HasErrorMessage("UUID byte array must be exactly 16 bytes"));

0 commit comments

Comments
 (0)