2 * Copyright 2004-present Facebook, Inc.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 #include <folly/experimental/logging/LogName.h>
20 std::string LogName::canonicalize(StringPiece input) {
22 cname.reserve(input.size());
24 // Ignore trailing '.'s
25 size_t end = input.size();
26 while (end > 0 && input[end - 1] == '.') {
30 bool ignoreDot = true;
31 for (size_t idx = 0; idx < end; ++idx) {
32 if (ignoreDot && input[idx] == '.') {
35 cname.push_back(input[idx]);
36 ignoreDot = (input[idx] == '.');
41 size_t LogName::hash(StringPiece name) {
42 // Code based on StringPiece::hash(), but which ignores leading and
43 // trailing '.' characters, as well as multiple consecutive '.' characters,
44 // so equivalent names result in the same hash.
47 size_t end = name.size();
48 while (end > 0 && name[end - 1] == '.') {
52 bool ignoreDot = true;
53 for (size_t idx = 0; idx < end; ++idx) {
54 if (ignoreDot && name[idx] == '.') {
57 hash = ((hash << 5) + hash) + name[idx];
58 // If this character was a '.', ignore subsequent consecutive '.'s
59 ignoreDot = (name[idx] == '.');
64 int LogName::cmp(StringPiece a, StringPiece b) {
65 // Ignore trailing '.'s
66 auto stripTrailingDots = [](StringPiece& s) {
67 while (!s.empty() && s.back() == '.') {
68 s.uncheckedSubtract(1);
74 // Advance ptr until it no longer points to a '.'
75 // This is used to skip over consecutive sequences of '.' characters.
76 auto skipOverDots = [](StringPiece& s) {
77 while (!s.empty() && s.front() == '.') {
78 s.uncheckedAdvance(1);
82 bool ignoreDot = true;
89 return b.empty() ? 0 : -1;
90 } else if (b.empty()) {
93 if (a.front() != b.front()) {
94 return a.front() - b.front();
96 ignoreDot = (a.front() == '.');
97 a.uncheckedAdvance(1);
98 b.uncheckedAdvance(1);
102 StringPiece LogName::getParent(StringPiece name) {
107 ssize_t idx = name.size();
109 // Skip over any trailing '.' characters
110 while (idx > 0 && name[idx - 1] == '.') {
114 // Now walk backwards to the next '.' character
115 while (idx > 0 && name[idx - 1] != '.') {
119 // And again skip over any '.' characters, in case there are multiple
120 // repeated characters.
121 while (idx > 0 && name[idx - 1] == '.') {
125 return StringPiece(name.begin(), idx);