]> git.proxmox.com Git - ceph.git/blob - ceph/src/arrow/cpp/src/plasma/common.cc
import quincy 17.2.0
[ceph.git] / ceph / src / arrow / cpp / src / plasma / common.cc
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 "plasma/common.h"
19
20 #include <limits>
21 #include <utility>
22
23 #include "arrow/util/ubsan.h"
24
25 #include "plasma/plasma_generated.h"
26
27 namespace fb = plasma::flatbuf;
28
29 namespace plasma {
30
31 namespace {
32
33 const char kErrorDetailTypeId[] = "plasma::PlasmaStatusDetail";
34
35 class PlasmaStatusDetail : public arrow::StatusDetail {
36 public:
37 explicit PlasmaStatusDetail(PlasmaErrorCode code) : code_(code) {}
38 const char* type_id() const override { return kErrorDetailTypeId; }
39 std::string ToString() const override {
40 const char* type;
41 switch (code()) {
42 case PlasmaErrorCode::PlasmaObjectExists:
43 type = "Plasma object is exists";
44 break;
45 case PlasmaErrorCode::PlasmaObjectNotFound:
46 type = "Plasma object is not found";
47 break;
48 case PlasmaErrorCode::PlasmaStoreFull:
49 type = "Plasma store is full";
50 break;
51 case PlasmaErrorCode::PlasmaObjectAlreadySealed:
52 type = "Plasma object is already sealed";
53 break;
54 default:
55 type = "Unknown plasma error";
56 break;
57 }
58 return std::string(type);
59 }
60 PlasmaErrorCode code() const { return code_; }
61
62 private:
63 PlasmaErrorCode code_;
64 };
65
66 bool IsPlasmaStatus(const arrow::Status& status, PlasmaErrorCode code) {
67 if (status.ok()) {
68 return false;
69 }
70 auto* detail = status.detail().get();
71 return detail != nullptr && detail->type_id() == kErrorDetailTypeId &&
72 static_cast<PlasmaStatusDetail*>(detail)->code() == code;
73 }
74
75 } // namespace
76
77 using arrow::Status;
78
79 arrow::Status MakePlasmaError(PlasmaErrorCode code, std::string message) {
80 arrow::StatusCode arrow_code = arrow::StatusCode::UnknownError;
81 switch (code) {
82 case PlasmaErrorCode::PlasmaObjectExists:
83 arrow_code = arrow::StatusCode::AlreadyExists;
84 break;
85 case PlasmaErrorCode::PlasmaObjectNotFound:
86 arrow_code = arrow::StatusCode::KeyError;
87 break;
88 case PlasmaErrorCode::PlasmaStoreFull:
89 arrow_code = arrow::StatusCode::CapacityError;
90 break;
91 case PlasmaErrorCode::PlasmaObjectAlreadySealed:
92 // Maybe a stretch?
93 arrow_code = arrow::StatusCode::TypeError;
94 break;
95 }
96 return arrow::Status(arrow_code, std::move(message),
97 std::make_shared<PlasmaStatusDetail>(code));
98 }
99
100 bool IsPlasmaObjectExists(const arrow::Status& status) {
101 return IsPlasmaStatus(status, PlasmaErrorCode::PlasmaObjectExists);
102 }
103 bool IsPlasmaObjectNotFound(const arrow::Status& status) {
104 return IsPlasmaStatus(status, PlasmaErrorCode::PlasmaObjectNotFound);
105 }
106 bool IsPlasmaObjectAlreadySealed(const arrow::Status& status) {
107 return IsPlasmaStatus(status, PlasmaErrorCode::PlasmaObjectAlreadySealed);
108 }
109 bool IsPlasmaStoreFull(const arrow::Status& status) {
110 return IsPlasmaStatus(status, PlasmaErrorCode::PlasmaStoreFull);
111 }
112
113 UniqueID UniqueID::from_binary(const std::string& binary) {
114 UniqueID id;
115 std::memcpy(&id, binary.data(), sizeof(id));
116 return id;
117 }
118
119 const uint8_t* UniqueID::data() const { return id_; }
120
121 uint8_t* UniqueID::mutable_data() { return id_; }
122
123 std::string UniqueID::binary() const {
124 return std::string(reinterpret_cast<const char*>(id_), kUniqueIDSize);
125 }
126
127 std::string UniqueID::hex() const {
128 constexpr char hex[] = "0123456789abcdef";
129 std::string result;
130 for (int i = 0; i < kUniqueIDSize; i++) {
131 unsigned int val = id_[i];
132 result.push_back(hex[val >> 4]);
133 result.push_back(hex[val & 0xf]);
134 }
135 return result;
136 }
137
138 // This code is from https://sites.google.com/site/murmurhash/
139 // and is public domain.
140 uint64_t MurmurHash64A(const void* key, int len, unsigned int seed) {
141 const uint64_t m = 0xc6a4a7935bd1e995;
142 const int r = 47;
143
144 uint64_t h = seed ^ (len * m);
145
146 const uint64_t* data = reinterpret_cast<const uint64_t*>(key);
147 const uint64_t* end = data + (len / 8);
148
149 while (data != end) {
150 uint64_t k = arrow::util::SafeLoad(data++);
151
152 k *= m;
153 k ^= k >> r;
154 k *= m;
155
156 h ^= k;
157 h *= m;
158 }
159
160 const unsigned char* data2 = reinterpret_cast<const unsigned char*>(data);
161
162 switch (len & 7) {
163 case 7:
164 h ^= uint64_t(data2[6]) << 48; // fall through
165 case 6:
166 h ^= uint64_t(data2[5]) << 40; // fall through
167 case 5:
168 h ^= uint64_t(data2[4]) << 32; // fall through
169 case 4:
170 h ^= uint64_t(data2[3]) << 24; // fall through
171 case 3:
172 h ^= uint64_t(data2[2]) << 16; // fall through
173 case 2:
174 h ^= uint64_t(data2[1]) << 8; // fall through
175 case 1:
176 h ^= uint64_t(data2[0]);
177 h *= m;
178 }
179
180 h ^= h >> r;
181 h *= m;
182 h ^= h >> r;
183
184 return h;
185 }
186
187 size_t UniqueID::hash() const { return MurmurHash64A(&id_[0], kUniqueIDSize, 0); }
188
189 bool UniqueID::operator==(const UniqueID& rhs) const {
190 return std::memcmp(data(), rhs.data(), kUniqueIDSize) == 0;
191 }
192
193 const PlasmaStoreInfo* plasma_config;
194
195 } // namespace plasma