YugabyteDB (2.13.0.0-b42, bfc6a6643e7399ac8a0e81d06a3ee6d6571b33ab)

Coverage Report

Created: 2022-03-09 17:30

/Users/deen/code/yugabyte-db/src/yb/gutil/strings/stringpiece.cc
Line
Count
Source (jump to first uncovered line)
1
// Copyright 2004 and onwards Google Inc.
2
//
3
// The following only applies to changes made to this file as part of YugaByte development.
4
//
5
// Portions Copyright (c) YugaByte, Inc.
6
//
7
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
8
// in compliance with the License.  You may obtain a copy of the License at
9
//
10
// http://www.apache.org/licenses/LICENSE-2.0
11
//
12
// Unless required by applicable law or agreed to in writing, software distributed under the License
13
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
14
// or implied.  See the License for the specific language governing permissions and limitations
15
// under the License.
16
//
17
//
18
#include "yb/gutil/strings/stringpiece.h"
19
20
#include <string.h>
21
22
#include <algorithm>
23
#include <string>
24
25
#include <glog/logging.h>
26
27
#include "yb/gutil/hash/hash.h"
28
#include "yb/gutil/stl_util.h"
29
#include "yb/gutil/strings/memutil.h"
30
31
using std::copy;
32
using std::max;
33
using std::min;
34
using std::reverse;
35
using std::sort;
36
using std::swap;
37
using std::string;
38
39
namespace std {
40
70.2M
  size_t hash<GStringPiece>::operator()(GStringPiece s) const {
41
70.2M
    return HashTo32(s.data(), s.size());
42
70.2M
  }
43
} // namespace std
44
45
2
std::ostream& operator<<(std::ostream& o, GStringPiece piece) {
46
2
  o.write(piece.data(), piece.size());
47
2
  return o;
48
2
}
49
50
GStringPiece::GStringPiece(GStringPiece x, size_type pos)
51
0
    : ptr_(x.ptr_ + pos), length_(x.length_ - pos) {
52
0
  DCHECK_LE(0, pos);
53
0
  DCHECK_LE(pos, x.length_);
54
0
}
55
56
GStringPiece::GStringPiece(GStringPiece x, size_type pos, size_type len)
57
0
    : ptr_(x.ptr_ + pos), length_(min(len, x.length_ - pos)) {
58
0
  DCHECK_LE(0, pos);
59
0
  DCHECK_LE(pos, x.length_);
60
0
  DCHECK_GE(len, 0);
61
0
}
62
63
0
void GStringPiece::CopyToString(string* target) const {
64
0
  STLAssignToString(target, ptr_, length_);
65
0
}
66
67
0
void GStringPiece::AppendToString(string* target) const {
68
0
  STLAppendToString(target, ptr_, length_);
69
0
}
70
71
0
GStringPiece::size_type GStringPiece::copy(char* buf, size_type n, size_type pos) const {
72
0
  size_type ret = min(length_ - pos, n);
73
0
  memcpy(buf, ptr_ + pos, ret);
74
0
  return ret;
75
0
}
76
77
1.74k
bool GStringPiece::contains(GStringPiece s) const {
78
1.74k
  return find(s, 0) != npos;
79
1.74k
}
80
81
843k
GStringPiece::size_type GStringPiece::find(GStringPiece s, size_type pos) const {
82
843k
  if (length_ <= 0 || pos > static_cast<size_type>(length_)) {
83
5.96k
    if (length_ == 0 && pos == 0 && s.length_ == 0) return 0;
84
5.96k
    return npos;
85
5.96k
  }
86
837k
  const char *result = memmatch(ptr_ + pos, length_ - pos,
87
837k
                                s.ptr_, s.length_);
88
469k
  return result ? result - ptr_ : npos;
89
837k
}
90
91
0
GStringPiece::size_type GStringPiece::find(char c, size_type pos) const {
92
0
  if (length_ <= 0 || pos >= static_cast<size_type>(length_)) {
93
0
    return npos;
94
0
  }
95
0
  const char* result = static_cast<const char*>(
96
0
      memchr(ptr_ + pos, c, length_ - pos));
97
0
  return result != nullptr ? result - ptr_ : npos;
98
0
}
99
100
0
GStringPiece::size_type GStringPiece::rfind(GStringPiece s, size_type pos) const {
101
0
  if (length_ < s.length_) return npos;
102
0
  const size_t ulen = length_;
103
0
  if (s.length_ == 0) return min(ulen, pos);
104
105
0
  const char* last = ptr_ + min(ulen - s.length_, pos) + s.length_;
106
0
  const char* result = std::find_end(ptr_, last, s.ptr_, s.ptr_ + s.length_);
107
0
  return result != last ? result - ptr_ : npos;
108
0
}
109
110
// Search range is [0..pos] inclusive.  If pos == npos, search everything.
111
0
GStringPiece::size_type GStringPiece::rfind(char c, size_type pos) const {
112
  // Note: memrchr() is not available on Windows.
113
0
  if (length_ <= 0) return npos;
114
0
  for (size_t i = min(pos + 1, length_); i > 0;) {
115
0
    --i;
116
0
    if (ptr_[i] == c) {
117
0
      return i;
118
0
    }
119
0
  }
120
0
  return npos;
121
0
}
122
123
// For each character in characters_wanted, sets the index corresponding
124
// to the ASCII code of that character to 1 in table.  This is used by
125
// the find_.*_of methods below to tell whether or not a character is in
126
// the lookup table in constant time.
127
// The argument `table' must be an array that is large enough to hold all
128
// the possible values of an unsigned char.  Thus it should be be declared
129
// as follows:
130
//   bool table[UCHAR_MAX + 1]
131
static inline void BuildLookupTable(GStringPiece characters_wanted,
132
0
                                    bool* table) {
133
0
  const size_t length = characters_wanted.length();
134
0
  const char* const data = characters_wanted.data();
135
0
  for (size_t i = 0; i < length; ++i) {
136
0
    table[static_cast<unsigned char>(data[i])] = true;
137
0
  }
138
0
}
139
140
0
GStringPiece::size_type GStringPiece::find_first_of(GStringPiece s, size_type pos) const {
141
0
  if (length_ <= 0 || s.length_ <= 0) {
142
0
    return npos;
143
0
  }
144
  // Avoid the cost of BuildLookupTable() for a single-character search.
145
0
  if (s.length_ == 1) return find_first_of(s.ptr_[0], pos);
146
147
0
  bool lookup[UCHAR_MAX + 1] = { false };
148
0
  BuildLookupTable(s, lookup);
149
0
  for (size_type i = pos; i < length_; ++i) {
150
0
    if (lookup[static_cast<unsigned char>(ptr_[i])]) {
151
0
      return i;
152
0
    }
153
0
  }
154
0
  return npos;
155
0
}
156
157
0
GStringPiece::size_type GStringPiece::find_first_not_of(GStringPiece s, size_type pos) const {
158
0
  if (length_ <= 0) return npos;
159
0
  if (s.length_ <= 0) return 0;
160
  // Avoid the cost of BuildLookupTable() for a single-character search.
161
0
  if (s.length_ == 1) return find_first_not_of(s.ptr_[0], pos);
162
163
0
  bool lookup[UCHAR_MAX + 1] = { false };
164
0
  BuildLookupTable(s, lookup);
165
0
  for (size_type i = pos; i < length_; ++i) {
166
0
    if (!lookup[static_cast<unsigned char>(ptr_[i])]) {
167
0
      return i;
168
0
    }
169
0
  }
170
0
  return npos;
171
0
}
172
173
0
GStringPiece::size_type GStringPiece::find_first_not_of(char c, size_type pos) const {
174
0
  if (length_ <= 0) return npos;
175
176
0
  for (; pos < length_; ++pos) {
177
0
    if (ptr_[pos] != c) {
178
0
      return pos;
179
0
    }
180
0
  }
181
0
  return npos;
182
0
}
183
184
0
GStringPiece::size_type GStringPiece::find_last_of(GStringPiece s, size_type pos) const {
185
0
  if (length_ <= 0 || s.length_ <= 0) return npos;
186
  // Avoid the cost of BuildLookupTable() for a single-character search.
187
0
  if (s.length_ == 1) return find_last_of(s.ptr_[0], pos);
188
189
0
  bool lookup[UCHAR_MAX + 1] = { false };
190
0
  BuildLookupTable(s, lookup);
191
0
  for (size_t i = min(pos + 1, length_); i > 0;) {
192
0
    --i;
193
0
    if (lookup[static_cast<unsigned char>(ptr_[i])]) {
194
0
      return i;
195
0
    }
196
0
  }
197
0
  return npos;
198
0
}
199
200
0
GStringPiece::size_type GStringPiece::find_last_not_of(GStringPiece s, size_type pos) const {
201
0
  if (length_ <= 0) return npos;
202
203
0
  size_type i = min(pos + 1, length_);
204
0
  if (s.length_ <= 0) return i - 1;
205
206
  // Avoid the cost of BuildLookupTable() for a single-character search.
207
0
  if (s.length_ == 1) return find_last_not_of(s.ptr_[0], pos);
208
209
0
  bool lookup[UCHAR_MAX + 1] = { false };
210
0
  BuildLookupTable(s, lookup);
211
0
  while (i > 0) {
212
0
    --i;
213
0
    if (!lookup[static_cast<unsigned char>(ptr_[i])]) {
214
0
      return i;
215
0
    }
216
0
  }
217
0
  return npos;
218
0
}
219
220
0
GStringPiece::size_type GStringPiece::find_last_not_of(char c, size_type pos) const {
221
0
  if (length_ <= 0) return npos;
222
223
0
  for (size_type i = min(pos + 1, length_); i > 0;) {
224
0
    --i;
225
0
    if (ptr_[i] != c) {
226
0
      return i;
227
0
    }
228
0
  }
229
0
  return npos;
230
0
}
231
232
0
GStringPiece GStringPiece::substr(size_type pos, size_type n) const {
233
0
  if (pos > length_) pos = length_;
234
0
  if (n > length_ - pos) n = length_ - pos;
235
0
  return GStringPiece(ptr_ + pos, n);
236
0
}
237
238
const GStringPiece::size_type GStringPiece::npos = size_type(-1);
239
240
5.67M
size_t GStringPiece::hash() const {
241
5.67M
  return HashStringThoroughly(data(), size());
242
5.67M
}