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