-
Notifications
You must be signed in to change notification settings - Fork 0
/
RoutingPrefix.cpp
89 lines (71 loc) · 2.17 KB
/
RoutingPrefix.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#include "RoutingPrefix.h"
#include <stdexcept>
#include <folly/String.h>
namespace facebook {
namespace memcache {
namespace mcrouter {
RoutingPrefix::RoutingPrefix(std::string prefix) : prefix_(std::move(prefix)) {
initFromPrefix();
}
RoutingPrefix::RoutingPrefix(const char* prefix) : prefix_(prefix) {
initFromPrefix();
}
RoutingPrefix::RoutingPrefix(folly::StringPiece prefix)
: prefix_(prefix.str()) {
initFromPrefix();
}
RoutingPrefix::RoutingPrefix(const RoutingPrefix& other) noexcept
: prefix_(other.prefix_) {
initFromPrefixUnsafe();
}
RoutingPrefix::RoutingPrefix(RoutingPrefix&& other) noexcept
: prefix_(std::move(other.prefix_)) {
initFromPrefixUnsafe();
}
RoutingPrefix& RoutingPrefix::operator=(const RoutingPrefix& other) noexcept {
return *this = RoutingPrefix(other);
}
RoutingPrefix& RoutingPrefix::operator=(RoutingPrefix&& other) noexcept {
swap(prefix_, other.prefix_);
initFromPrefixUnsafe();
return *this;
}
void RoutingPrefix::initFromPrefix() {
if (prefix_.empty()) {
throw std::invalid_argument("Routing prefix can not be empty");
}
// add trailing end leading slash, if missing
if (prefix_[0] != '/') {
prefix_ = "/" + prefix_;
}
if (prefix_.back() != '/') {
prefix_ += "/";
}
std::vector<folly::StringPiece> parts;
folly::split("/", prefix_, parts);
// empty, region (non-empty), cluster (non-empty), empty
if (parts.size() != 4 || !parts[0].empty() || parts[1].empty() ||
parts[2].empty() || !parts[3].empty()) {
throw std::invalid_argument(
"Routing prefix (" + prefix_ +
") should be of the form /region/cluster/");
}
region_ = parts[1];
cluster_ = parts[2];
}
void RoutingPrefix::initFromPrefixUnsafe() {
auto splitPos = prefix_.find('/', 1);
assert(splitPos != std::string::npos);
region_.assign(prefix_.data() + 1, prefix_.data() + splitPos);
cluster_.assign(
prefix_.data() + splitPos + 1, prefix_.data() + prefix_.size() - 1);
}
}
}
} // facebook::memcache::mcrouter