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{
37 using metadata_key = std::string_view;
38 using metadata_value = std::string_view;
39 using metadata_pair = std::pair<metadata_key, metadata_value>;
40
41 // Helper function to extract an int32 from a char buffer
42 SPARROW_API int32_t extract_int32(const char*& ptr);
43
44 class key_value_view;
45
47 {
48 public:
49
50 using iterator_category = std::input_iterator_tag;
52 using difference_type = std::ptrdiff_t;
55
56 SPARROW_API key_value_view_iterator(const key_value_view& parent, int32_t index);
57
59
61
63 {
64 return lhs.m_index == rhs.m_index;
65 }
66
67 private:
68
69 SPARROW_API std::string_view extract_string_view();
70 SPARROW_API void extract_key_value();
71
72 const key_value_view* m_parent;
73 int32_t m_index;
74 const char* m_current;
75 std::string_view m_key;
76 std::string_view m_value;
77 };
78
79 // Custom view to lazily extract key/value pairs from the buffer
80 class key_value_view : public std::ranges::view_interface<key_value_view>
81 {
82 public:
83
84 SPARROW_API key_value_view(const char* ptr);
85
86 [[nodiscard]] SPARROW_API key_value_view_iterator cbegin() const;
87
88 [[nodiscard]] SPARROW_API key_value_view_iterator begin() const;
89
90 [[nodiscard]] SPARROW_API key_value_view_iterator cend() const;
91
92 [[nodiscard]] SPARROW_API key_value_view_iterator end() const;
93
94 [[nodiscard]] SPARROW_API size_t size() const;
95
96 private:
97
98 const char* m_ptr;
99 int32_t m_num_pairs = 0;
100
101 friend key_value_view_iterator;
102 };
103
104 template <typename T>
105 concept input_metadata_container = std::ranges::input_range<T>
106 && std::same_as<std::ranges::range_value_t<T>, metadata_pair>;
107
108 template <input_metadata_container T>
109 std::string get_metadata_from_key_values(const T& metadata)
110 {
111 const auto number_of_key_values = static_cast<int32_t>(metadata.size());
112 const size_t metadata_size = std::accumulate(
113 metadata.cbegin(),
114 metadata.cend(),
115 size_t(0),
116 [](size_t acc, const auto& pair)
117 {
118 return acc + sizeof(int32_t) // byte length of key
119 + pair.first.size() // number of bytes of key
120 + sizeof(int32_t) // byte length of value
121 + pair.second.size(); // number of bytes of value
122 }
123 );
124 const size_t total_size = sizeof(int32_t) + metadata_size;
125 std::string metadata_buf(total_size, '\0');
126 char* metadata_ptr = metadata_buf.data();
127 std::memcpy(metadata_ptr, &number_of_key_values, sizeof(int32_t));
128 metadata_ptr += sizeof(int32_t);
129 for (const auto& [key, value] : metadata)
130 {
131 SPARROW_ASSERT_TRUE(std::cmp_less(key.size(), std::numeric_limits<int32_t>::max()));
132 SPARROW_ASSERT_TRUE(std::cmp_less(value.size(), std::numeric_limits<int32_t>::max()));
133
134 const auto key_size = static_cast<int32_t>(key.size());
135 std::memcpy(metadata_ptr, &key_size, sizeof(int32_t));
136 metadata_ptr += sizeof(int32_t);
137
138 sparrow::ranges::copy(key, metadata_ptr);
139 metadata_ptr += key.size();
140
141 const auto value_size = static_cast<int32_t>(value.size());
142 std::memcpy(metadata_ptr, &value_size, sizeof(int32_t));
143 metadata_ptr += sizeof(int32_t);
144
145 sparrow::ranges::copy(value, metadata_ptr);
146 metadata_ptr += value.size();
147 }
148 return metadata_buf;
149 }
150}
151
152
153#if defined(__cpp_lib_format) && !defined(__cpp_lib_format_ranges)
154
155template <>
156struct std::formatter<sparrow::key_value_view>
157{
158 constexpr auto parse(std::format_parse_context& ctx)
159 {
160 return ctx.begin(); // Simple implementation
161 }
162
163 auto format(const sparrow::key_value_view& array, std::format_context& ctx) const
164 {
165 auto out = ctx.out();
166 *out++ = '<';
167
168 bool first = true;
169 for (const auto& elem : array)
170 {
171 if (!first)
172 {
173 *out++ = ',';
174 *out++ = ' ';
175 }
176 out = std::format_to(out, "({}:{})", elem.first, elem.second);
177 first = false;
178 }
179
180 *out++ = '>';
181 return out;
182 }
183};
184
185inline std::ostream& operator<<(std::ostream& os, const sparrow::key_value_view& value)
186{
187 os << std::format("{}", value);
188 return os;
189}
190
191#endif
SPARROW_API key_value_view_iterator & operator++()
friend bool operator==(const key_value_view_iterator &lhs, const key_value_view_iterator &rhs)
Definition metadata.hpp:62
SPARROW_API key_value_view_iterator(const key_value_view &parent, int32_t index)
SPARROW_API value_type operator*() const
std::input_iterator_tag iterator_category
Definition metadata.hpp:50
SPARROW_API key_value_view_iterator begin() const
SPARROW_API size_t size() const
SPARROW_API key_value_view_iterator end() const
SPARROW_API key_value_view_iterator cend() const
SPARROW_API key_value_view(const char *ptr)
SPARROW_API key_value_view_iterator cbegin() const
#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:116
SPARROW_API int32_t extract_int32(const char *&ptr)
std::string get_metadata_from_key_values(const T &metadata)
Definition metadata.hpp:109
std::string_view metadata_value
Definition metadata.hpp:38
std::string_view metadata_key
Definition metadata.hpp:37
std::pair< metadata_key, metadata_value > metadata_pair
Definition metadata.hpp:39
std::ostream & operator<<(std::ostream &os, const sparrow::nullval_t &)
Definition nullable.hpp:933