]> git.proxmox.com Git - ceph.git/blame - ceph/src/arrow/cpp/src/plasma/common.cc
import quincy 17.2.0
[ceph.git] / ceph / src / arrow / cpp / src / plasma / common.cc
CommitLineData
1d09f67e
TL
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
27namespace fb = plasma::flatbuf;
28
29namespace plasma {
30
31namespace {
32
33const char kErrorDetailTypeId[] = "plasma::PlasmaStatusDetail";
34
35class 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
66bool 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
77using arrow::Status;
78
79arrow::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
100bool IsPlasmaObjectExists(const arrow::Status& status) {
101 return IsPlasmaStatus(status, PlasmaErrorCode::PlasmaObjectExists);
102}
103bool IsPlasmaObjectNotFound(const arrow::Status& status) {
104 return IsPlasmaStatus(status, PlasmaErrorCode::PlasmaObjectNotFound);
105}
106bool IsPlasmaObjectAlreadySealed(const arrow::Status& status) {
107 return IsPlasmaStatus(status, PlasmaErrorCode::PlasmaObjectAlreadySealed);
108}
109bool IsPlasmaStoreFull(const arrow::Status& status) {
110 return IsPlasmaStatus(status, PlasmaErrorCode::PlasmaStoreFull);
111}
112
113UniqueID UniqueID::from_binary(const std::string& binary) {
114 UniqueID id;
115 std::memcpy(&id, binary.data(), sizeof(id));
116 return id;
117}
118
119const uint8_t* UniqueID::data() const { return id_; }
120
121uint8_t* UniqueID::mutable_data() { return id_; }
122
123std::string UniqueID::binary() const {
124 return std::string(reinterpret_cast<const char*>(id_), kUniqueIDSize);
125}
126
127std::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.
140uint64_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
187size_t UniqueID::hash() const { return MurmurHash64A(&id_[0], kUniqueIDSize, 0); }
188
189bool UniqueID::operator==(const UniqueID& rhs) const {
190 return std::memcmp(data(), rhs.data(), kUniqueIDSize) == 0;
191}
192
193const PlasmaStoreInfo* plasma_config;
194
195} // namespace plasma