1// Licensed to the Apache Software Foundation (ASF) under one
2// or more contributor license agreements. See the NOTICE file
3// distributed with this work for additional information
4// regarding copyright ownership. The ASF licenses this file
5// to you under the Apache License, Version 2.0 (the
6// "License"); you may not use this file except in compliance
7// with the License. You may obtain a copy of the License at
8//
9// http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing,
12// software distributed under the License is distributed on an
13// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14// KIND, either express or implied. See the License for the
15// specific language governing permissions and limitations
16// under the License.
17
18#include <algorithm>
19#include <cstddef>
20#include <cstdint>
21#include <memory>
22#include <sstream>
23#include <string>
24#include <unordered_map>
25#include <utility>
26#include <vector>
27
28#include "arrow/util/key_value_metadata.h"
29#include "arrow/util/logging.h"
30
31using std::size_t;
32
33namespace arrow {
34
35static std::vector<std::string> UnorderedMapKeys(
36 const std::unordered_map<std::string, std::string>& map) {
37 std::vector<std::string> keys;
38 keys.reserve(map.size());
39 for (const auto& pair : map) {
40 keys.push_back(pair.first);
41 }
42 return keys;
43}
44
45static std::vector<std::string> UnorderedMapValues(
46 const std::unordered_map<std::string, std::string>& map) {
47 std::vector<std::string> values;
48 values.reserve(map.size());
49 for (const auto& pair : map) {
50 values.push_back(pair.second);
51 }
52 return values;
53}
54
55KeyValueMetadata::KeyValueMetadata() : keys_(), values_() {}
56
57KeyValueMetadata::KeyValueMetadata(
58 const std::unordered_map<std::string, std::string>& map)
59 : keys_(UnorderedMapKeys(map)), values_(UnorderedMapValues(map)) {
60 DCHECK_EQ(keys_.size(), values_.size());
61}
62
63KeyValueMetadata::KeyValueMetadata(const std::vector<std::string>& keys,
64 const std::vector<std::string>& values)
65 : keys_(keys), values_(values) {
66 DCHECK_EQ(keys.size(), values.size());
67}
68
69void KeyValueMetadata::ToUnorderedMap(
70 std::unordered_map<std::string, std::string>* out) const {
71 DCHECK_NE(out, nullptr);
72 const int64_t n = size();
73 out->reserve(n);
74 for (int64_t i = 0; i < n; ++i) {
75 out->insert(std::make_pair(key(i), value(i)));
76 }
77}
78
79void KeyValueMetadata::Append(const std::string& key, const std::string& value) {
80 keys_.push_back(key);
81 values_.push_back(value);
82}
83
84void KeyValueMetadata::reserve(int64_t n) {
85 DCHECK_GE(n, 0);
86 const auto m = static_cast<size_t>(n);
87 keys_.reserve(m);
88 values_.reserve(m);
89}
90
91int64_t KeyValueMetadata::size() const {
92 DCHECK_EQ(keys_.size(), values_.size());
93 return static_cast<int64_t>(keys_.size());
94}
95
96std::string KeyValueMetadata::key(int64_t i) const {
97 DCHECK_GE(i, 0);
98 DCHECK_LT(static_cast<size_t>(i), keys_.size());
99 return keys_[i];
100}
101
102std::string KeyValueMetadata::value(int64_t i) const {
103 DCHECK_GE(i, 0);
104 DCHECK_LT(static_cast<size_t>(i), values_.size());
105 return values_[i];
106}
107
108std::shared_ptr<KeyValueMetadata> KeyValueMetadata::Copy() const {
109 return std::make_shared<KeyValueMetadata>(keys_, values_);
110}
111
112bool KeyValueMetadata::Equals(const KeyValueMetadata& other) const {
113 return size() == other.size() &&
114 std::equal(keys_.cbegin(), keys_.cend(), other.keys_.cbegin()) &&
115 std::equal(values_.cbegin(), values_.cend(), other.values_.cbegin());
116}
117
118std::string KeyValueMetadata::ToString() const {
119 std::stringstream buffer;
120
121 buffer << "\n-- metadata --";
122 for (int64_t i = 0; i < size(); ++i) {
123 buffer << "\n" << keys_[i] << ": " << values_[i];
124 }
125
126 return buffer.str();
127}
128
129std::shared_ptr<KeyValueMetadata> key_value_metadata(
130 const std::unordered_map<std::string, std::string>& pairs) {
131 return std::make_shared<KeyValueMetadata>(pairs);
132}
133
134} // namespace arrow
135