sparrow ..
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;
44 using metadata_key_const_reference = std::string_view;
45
52 using metadata_value = std::string;
53 using metadata_value_const_reference = std::string_view;
54
61 using metadata_pair = std::pair<metadata_key, metadata_value>;
62 using metadata_pair_const_reference = std::pair<metadata_key_const_reference, metadata_value_const_reference>;
63
77 SPARROW_API int32_t extract_int32(const char*& ptr);
78
79 class key_value_view;
80
96 {
97 public:
98
99 // using iterator_category = std::input_iterator_tag;
101 using difference_type = std::ptrdiff_t;
104 using iterator_concept = std::forward_iterator_tag;
105
106
119
131
141
150
161 {
162 return lhs.m_index == rhs.m_index;
163 }
164
165 private:
166
178 SPARROW_API std::string_view extract_string_view();
179
190 SPARROW_API void extract_key_value();
191
192 const key_value_view* m_parent;
193 int32_t m_index;
194 const char* m_current;
195 std::string_view m_key;
196 std::string_view m_value;
197 };
198
220 class key_value_view : public std::ranges::view_interface<key_value_view>
221 {
222 public:
223
234 SPARROW_API key_value_view(const char* ptr);
235
244 [[nodiscard]] SPARROW_API key_value_view_iterator cbegin() const;
245
254 [[nodiscard]] SPARROW_API key_value_view_iterator begin() const;
255
264 [[nodiscard]] SPARROW_API key_value_view_iterator cend() const;
265
274 [[nodiscard]] SPARROW_API key_value_view_iterator end() const;
275
284 [[nodiscard]] SPARROW_API size_t size() const;
285
286 private:
287
288 const char* m_ptr;
289 int32_t m_num_pairs = 0;
290
291 friend key_value_view_iterator;
292 };
293
303 template <typename T>
304 concept input_metadata_container = std::ranges::input_range<T>
305 && std::same_as<std::ranges::range_value_t<T>, metadata_pair>;
306
337 template <input_metadata_container T>
338 std::string get_metadata_from_key_values(const T& metadata)
339 {
340 // Check that the number of key-value pairs fits in int32_t
341 SPARROW_ASSERT_TRUE(std::cmp_less(metadata.size(), std::numeric_limits<int32_t>::max()));
342 const auto number_of_key_values = static_cast<int32_t>(metadata.size());
343
344 const size_t metadata_size = std::accumulate(
345 metadata.cbegin(),
346 metadata.cend(),
347 size_t(0),
348 [](size_t acc, const auto& pair)
349 {
350 return acc + sizeof(int32_t) // byte length of key
351 + pair.first.size() // number of bytes of key
352 + sizeof(int32_t) // byte length of value
353 + pair.second.size(); // number of bytes of value
354 }
355 );
356 const size_t total_size = sizeof(int32_t) + metadata_size;
357 std::string metadata_buf(total_size, '\0');
358
359 // Use iterators instead of pointer arithmetic to avoid warnings
360 auto metadata_iter = metadata_buf.begin();
361 std::memcpy(&(*metadata_iter), &number_of_key_values, sizeof(int32_t));
362 std::advance(metadata_iter, sizeof(int32_t));
363
364 for (const auto& [key, value] : metadata)
365 {
366 SPARROW_ASSERT_TRUE(std::cmp_less(key.size(), std::numeric_limits<int32_t>::max()));
367 SPARROW_ASSERT_TRUE(std::cmp_less(value.size(), std::numeric_limits<int32_t>::max()));
368
369 const auto key_size = static_cast<int32_t>(key.size());
370 std::memcpy(&(*metadata_iter), &key_size, sizeof(int32_t));
371 std::advance(metadata_iter, sizeof(int32_t));
372
373 sparrow::ranges::copy(key, &(*metadata_iter));
374 std::advance(metadata_iter, key.size());
375
376 const auto value_size = static_cast<int32_t>(value.size());
377 std::memcpy(&(*metadata_iter), &value_size, sizeof(int32_t));
378 std::advance(metadata_iter, sizeof(int32_t));
379
380 sparrow::ranges::copy(value, &(*metadata_iter));
381 std::advance(metadata_iter, value.size());
382 }
383 return metadata_buf;
384 }
385}
386
387#if defined(__cpp_lib_format)
388
389
390template <>
391struct std::formatter<sparrow::key_value_view>
392{
393 constexpr auto parse(std::format_parse_context& ctx)
394 {
395 return ctx.begin(); // Simple implementation
396 }
397
398 auto format(const sparrow::key_value_view& array, std::format_context& ctx) const
399 {
400 auto out = ctx.out();
401 *out++ = '<';
402
403 bool first = true;
404 for (const auto& elem : array)
405 {
406 if (!first)
407 {
408 *out++ = ',';
409 *out++ = ' ';
410 }
411 out = std::format_to(out, "({}:{})", elem.first, elem.second);
412 first = false;
413 }
414
415 *out++ = '>';
416 return out;
417 }
418};
419
420namespace sparrow
421{
422 inline std::ostream& operator<<(std::ostream& os, const key_value_view& value)
423 {
424 os << std::format("{}", value);
425 return os;
426 }
427}
428
429#endif
SPARROW_API key_value_view_iterator operator++(int)
Advances the iterator to the next key-value pair.
std::forward_iterator_tag iterator_concept
Definition metadata.hpp:104
SPARROW_API key_value_view_iterator & operator++()
Advances the iterator to the next key-value pair.
metadata_pair_const_reference value_type
Definition metadata.hpp:100
friend bool operator==(const key_value_view_iterator &lhs, const key_value_view_iterator &rhs)
Equality comparison operator for iterators.
Definition metadata.hpp:160
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.
Custom view for lazily extracting key-value pairs from a binary buffer.
Definition metadata.hpp:221
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:304
#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::pair< metadata_key_const_reference, metadata_value_const_reference > metadata_pair_const_reference
Definition metadata.hpp:62
std::string get_metadata_from_key_values(const T &metadata)
Converts a container of key-value pairs to binary metadata format.
Definition metadata.hpp:338
std::string_view metadata_value_const_reference
Definition metadata.hpp:53
std::string_view metadata_key_const_reference
Definition metadata.hpp:44
std::ostream & operator<<(std::ostream &os, const nullval_t &)
std::pair< metadata_key, metadata_value > metadata_pair
Type alias for metadata key-value pairs.
Definition metadata.hpp:61
std::string metadata_key
Type alias for metadata keys.
Definition metadata.hpp:43
std::string metadata_value
Type alias for metadata values.
Definition metadata.hpp:52