sparrow 0.9.0
Loading...
Searching...
No Matches
metadata.hpp
Go to the documentation of this file.
1// Copyright 2024 Man Group Operations Limited
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#pragma once
16
17#include <concepts>
18#include <cstddef>
19#include <cstdint>
20#include <cstring>
21#include <numeric>
22#include <ranges>
23#include <string_view>
24#include <utility>
25
29
30#if defined(__cpp_lib_format)
31# include <format>
32# include <ostream>
33#endif
34
35namespace sparrow
36{
43 using metadata_key = std::string_view;
44
51 using metadata_value = std::string_view;
52
59 using metadata_pair = std::pair<metadata_key, metadata_value>;
60
74 SPARROW_API int32_t extract_int32(const char*& ptr);
75
76 class key_value_view;
77
93 {
94 public:
95
96 using iterator_category = std::input_iterator_tag;
98 using difference_type = std::ptrdiff_t;
101
114
126
137
148 {
149 return lhs.m_index == rhs.m_index;
150 }
151
152 private:
153
165 SPARROW_API std::string_view extract_string_view();
166
177 SPARROW_API void extract_key_value();
178
179 const key_value_view* m_parent;
180 int32_t m_index;
181 const char* m_current;
182 std::string_view m_key;
183 std::string_view m_value;
184 };
185
207 class key_value_view : public std::ranges::view_interface<key_value_view>
208 {
209 public:
210
221 SPARROW_API key_value_view(const char* ptr);
222
231 [[nodiscard]] SPARROW_API key_value_view_iterator cbegin() const;
232
241 [[nodiscard]] SPARROW_API key_value_view_iterator begin() const;
242
251 [[nodiscard]] SPARROW_API key_value_view_iterator cend() const;
252
261 [[nodiscard]] SPARROW_API key_value_view_iterator end() const;
262
271 [[nodiscard]] SPARROW_API size_t size() const;
272
273 private:
274
275 const char* m_ptr;
276 int32_t m_num_pairs = 0;
277
278 friend key_value_view_iterator;
279 };
280
290 template <typename T>
291 concept input_metadata_container = std::ranges::input_range<T>
292 && std::same_as<std::ranges::range_value_t<T>, metadata_pair>;
293
322 template <input_metadata_container T>
323 std::string get_metadata_from_key_values(const T& metadata)
324 {
325 const auto number_of_key_values = static_cast<int32_t>(metadata.size());
326 const size_t metadata_size = std::accumulate(
327 metadata.cbegin(),
328 metadata.cend(),
329 size_t(0),
330 [](size_t acc, const auto& pair)
331 {
332 return acc + sizeof(int32_t) // byte length of key
333 + pair.first.size() // number of bytes of key
334 + sizeof(int32_t) // byte length of value
335 + pair.second.size(); // number of bytes of value
336 }
337 );
338 const size_t total_size = sizeof(int32_t) + metadata_size;
339 std::string metadata_buf(total_size, '\0');
340 char* metadata_ptr = metadata_buf.data();
341 std::memcpy(metadata_ptr, &number_of_key_values, sizeof(int32_t));
342 metadata_ptr += sizeof(int32_t);
343 for (const auto& [key, value] : metadata)
344 {
345 SPARROW_ASSERT_TRUE(std::cmp_less(key.size(), std::numeric_limits<int32_t>::max()));
346 SPARROW_ASSERT_TRUE(std::cmp_less(value.size(), std::numeric_limits<int32_t>::max()));
347
348 const auto key_size = static_cast<int32_t>(key.size());
349 std::memcpy(metadata_ptr, &key_size, sizeof(int32_t));
350 metadata_ptr += sizeof(int32_t);
351
352 sparrow::ranges::copy(key, metadata_ptr);
353 metadata_ptr += key.size();
354
355 const auto value_size = static_cast<int32_t>(value.size());
356 std::memcpy(metadata_ptr, &value_size, sizeof(int32_t));
357 metadata_ptr += sizeof(int32_t);
358
359 sparrow::ranges::copy(value, metadata_ptr);
360 metadata_ptr += value.size();
361 }
362 return metadata_buf;
363 }
364}
365
366#if defined(__cpp_lib_format)
367
368
369template <>
370struct std::formatter<sparrow::key_value_view>
371{
372 constexpr auto parse(std::format_parse_context& ctx)
373 {
374 return ctx.begin(); // Simple implementation
375 }
376
377 auto format(const sparrow::key_value_view& array, std::format_context& ctx) const
378 {
379 auto out = ctx.out();
380 *out++ = '<';
381
382 bool first = true;
383 for (const auto& elem : array)
384 {
385 if (!first)
386 {
387 *out++ = ',';
388 *out++ = ' ';
389 }
390 out = std::format_to(out, "({}:{})", elem.first, elem.second);
391 first = false;
392 }
393
394 *out++ = '>';
395 return out;
396 }
397};
398
399inline std::ostream& operator<<(std::ostream& os, const sparrow::key_value_view& value)
400{
401 os << std::format("{}", value);
402 return os;
403}
404
405#endif
SPARROW_API key_value_view_iterator & operator++()
Advances the iterator to the next key-value pair.
friend bool operator==(const key_value_view_iterator &lhs, const key_value_view_iterator &rhs)
Equality comparison operator for iterators.
Definition metadata.hpp:147
SPARROW_API key_value_view_iterator(const key_value_view &parent, int32_t index)
Constructs an iterator for the given view at the specified index.
SPARROW_API value_type operator*() const
Dereferences the iterator to get the current key-value pair.
std::input_iterator_tag iterator_category
Definition metadata.hpp:96
Custom view for lazily extracting key-value pairs from a binary buffer.
Definition metadata.hpp:208
SPARROW_API key_value_view_iterator begin() const
Gets iterator to the beginning of the metadata pairs.
SPARROW_API size_t size() const
Gets the number of key-value pairs in the metadata.
SPARROW_API key_value_view_iterator end() const
Gets iterator to the end of the metadata pairs.
SPARROW_API key_value_view_iterator cend() const
Gets const iterator to the end of the metadata pairs.
SPARROW_API key_value_view(const char *ptr)
Constructs a view over the given binary metadata buffer.
SPARROW_API key_value_view_iterator cbegin() const
Gets const iterator to the beginning of the metadata pairs.
Concept for input containers that can provide metadata pairs.
Definition metadata.hpp:291
#define SPARROW_API
Definition config.hpp:38
#define SPARROW_ASSERT_TRUE(expr__)
constexpr std::ranges::copy_result< std::ranges::borrowed_iterator_t< R >, O > copy(R &&r, O result)
Definition ranges.hpp:117
SPARROW_API int32_t extract_int32(const char *&ptr)
Helper function to extract a 32-bit integer from a character buffer.
std::string get_metadata_from_key_values(const T &metadata)
Converts a container of key-value pairs to binary metadata format.
Definition metadata.hpp:323
std::string_view metadata_value
Type alias for metadata values.
Definition metadata.hpp:51
std::string_view metadata_key
Type alias for metadata keys.
Definition metadata.hpp:43
std::pair< metadata_key, metadata_value > metadata_pair
Type alias for metadata key-value pairs.
Definition metadata.hpp:59
std::ostream & operator<<(std::ostream &os, const sparrow::nullval_t &)