timeout_encoding.cc
Go to the documentation of this file.
1 /*
2  *
3  * Copyright 2015 gRPC authors.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * 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, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18 
20 
22 
23 #include "absl/base/attributes.h"
24 
25 #include <grpc/support/log.h>
26 #include <grpc/support/time.h>
27 
28 namespace grpc_core {
29 
30 namespace {
31 
32 int64_t DivideRoundingUp(int64_t dividend, int64_t divisor) {
33  return (dividend + divisor - 1) / divisor;
34 }
35 
36 constexpr int64_t kSecondsPerMinute = 60;
37 constexpr int64_t kMinutesPerHour = 60;
38 constexpr int64_t kMaxHours = 27000;
39 
40 bool IsAllSpace(const uint8_t* p, const uint8_t* end) {
41  while (p != end && *p == ' ') p++;
42  return p == end;
43 }
44 
45 } // namespace
46 
48  return Timeout::FromMillis(duration.millis());
49 }
50 
51 double Timeout::RatioVersus(Timeout other) const {
52  double a = AsDuration().millis();
53  double b = other.AsDuration().millis();
54  if (b == 0) {
55  if (a > 0) return 100;
56  if (a < 0) return -100;
57  return 0;
58  }
59  return 100 * (a / b - 1);
60 }
61 
64  switch (unit_) {
65  case Unit::kNanoseconds:
66  return Duration::Zero();
70  return Duration::Milliseconds(value * 10);
72  return Duration::Milliseconds(value * 100);
73  case Unit::kSeconds:
74  return Duration::Seconds(value);
75  case Unit::kTenSeconds:
76  return Duration::Seconds(value * 10);
78  return Duration::Seconds(value * 100);
79  case Unit::kMinutes:
80  return Duration::Minutes(value);
81  case Unit::kTenMinutes:
82  return Duration::Minutes(value * 10);
84  return Duration::Minutes(value * 100);
85  case Unit::kHours:
86  return Duration::Hours(value);
87  }
89 }
90 
92  char buf[10];
93  char* p = buf;
94  uint16_t n = value_;
95  int digits;
96  if (n >= 10000) {
97  digits = 5;
98  } else if (n >= 1000) {
99  digits = 4;
100  } else if (n >= 100) {
101  digits = 3;
102  } else if (n >= 10) {
103  digits = 2;
104  } else {
105  digits = 1;
106  }
107  switch (digits) {
108  case 5:
109  *p++ = '0' + n / 10000;
110  n %= 10000;
112  case 4:
113  *p++ = '0' + n / 1000;
114  n %= 1000;
116  case 3:
117  *p++ = '0' + n / 100;
118  n %= 100;
120  case 2:
121  *p++ = '0' + n / 10;
122  n %= 10;
124  case 1:
125  *p++ = '0' + n;
126  }
127  switch (unit_) {
128  case Unit::kNanoseconds:
129  *p++ = 'n';
130  break;
132  *p++ = '0';
135  *p++ = '0';
137  case Unit::kMilliseconds:
138  *p++ = 'm';
139  break;
141  *p++ = '0';
143  case Unit::kTenSeconds:
144  *p++ = '0';
146  case Unit::kSeconds:
147  *p++ = 'S';
148  break;
150  *p++ = '0';
152  case Unit::kTenMinutes:
153  *p++ = '0';
155  case Unit::kMinutes:
156  *p++ = 'M';
157  break;
158  case Unit::kHours:
159  *p++ = 'H';
160  break;
161  }
162  return Slice::FromCopiedBuffer(buf, p - buf);
163 }
164 
166  if (millis <= 0) {
167  return Timeout(1, Unit::kNanoseconds);
168  } else if (millis < 1000) {
169  return Timeout(millis, Unit::kMilliseconds);
170  } else if (millis < 10000) {
171  int64_t value = DivideRoundingUp(millis, 10);
172  if (value % 100 != 0) return Timeout(value, Unit::kTenMilliseconds);
173  } else if (millis < 100000) {
174  int64_t value = DivideRoundingUp(millis, 100);
175  if (value % 10 != 0) return Timeout(value, Unit::kHundredMilliseconds);
176  }
177  return Timeout::FromSeconds(DivideRoundingUp(millis, 1000));
178 }
179 
182  if (seconds < 1000) {
183  if (seconds % kSecondsPerMinute != 0) {
184  return Timeout(seconds, Unit::kSeconds);
185  }
186  } else if (seconds < 10000) {
187  int64_t value = DivideRoundingUp(seconds, 10);
188  if ((value * 10) % kSecondsPerMinute != 0) {
190  }
191  } else if (seconds < 100000) {
192  int64_t value = DivideRoundingUp(seconds, 100);
193  if ((value * 100) % kSecondsPerMinute != 0) {
195  }
196  }
197  return Timeout::FromMinutes(DivideRoundingUp(seconds, kSecondsPerMinute));
198 }
199 
201  GPR_DEBUG_ASSERT(minutes != 0);
202  if (minutes < 1000) {
203  if (minutes % kMinutesPerHour != 0) {
204  return Timeout(minutes, Unit::kMinutes);
205  }
206  } else if (minutes < 10000) {
207  int64_t value = DivideRoundingUp(minutes, 10);
208  if ((value * 10) % kMinutesPerHour != 0) {
210  }
211  } else if (minutes < 100000) {
212  int64_t value = DivideRoundingUp(minutes, 100);
213  if ((value * 100) % kMinutesPerHour != 0) {
215  }
216  }
217  return Timeout::FromHours(DivideRoundingUp(minutes, kMinutesPerHour));
218 }
219 
221  GPR_DEBUG_ASSERT(hours != 0);
222  if (hours < kMaxHours) {
223  return Timeout(hours, Unit::kHours);
224  }
225  return Timeout(kMaxHours, Unit::kHours);
226 }
227 
229  int32_t x = 0;
230  const uint8_t* p = text.begin();
231  const uint8_t* end = text.end();
232  int have_digit = 0;
233  /* skip whitespace */
234  for (; p != end && *p == ' '; p++) {
235  }
236  /* decode numeric part */
237  for (; p != end && *p >= '0' && *p <= '9'; p++) {
238  int32_t digit = static_cast<int32_t>(*p - static_cast<uint8_t>('0'));
239  have_digit = 1;
240  /* spec allows max. 8 digits, but we allow values up to 1,000,000,000 */
241  if (x >= (100 * 1000 * 1000)) {
242  if (x != (100 * 1000 * 1000) || digit != 0) {
243  return Duration::Infinity();
244  }
245  }
246  x = x * 10 + digit;
247  }
248  if (!have_digit) return absl::nullopt;
249  /* skip whitespace */
250  for (; p != end && *p == ' '; p++) {
251  }
252  if (p == end) return absl::nullopt;
253  /* decode unit specifier */
255  switch (*p) {
256  case 'n':
257  timeout =
259  break;
260  case 'u':
261  timeout =
263  break;
264  case 'm':
266  break;
267  case 'S':
269  break;
270  case 'M':
272  break;
273  case 'H':
275  break;
276  default:
277  return absl::nullopt;
278  }
279  p++;
280  if (!IsAllSpace(p, end)) return absl::nullopt;
281  return timeout;
282 }
283 
284 } // namespace grpc_core
grpc_core::Duration::Hours
static constexpr Duration Hours(int64_t hours)
Definition: src/core/lib/gprpp/time.h:143
absl::time_internal::cctz::seconds
std::chrono::duration< std::int_fast64_t > seconds
Definition: abseil-cpp/absl/time/internal/cctz/include/cctz/time_zone.h:40
grpc_core::Timeout::Unit::kHundredSeconds
@ kHundredSeconds
log.h
grpc_core::ParseTimeout
absl::optional< Duration > ParseTimeout(const Slice &text)
Definition: timeout_encoding.cc:228
GPR_DEBUG_ASSERT
#define GPR_DEBUG_ASSERT(x)
Definition: include/grpc/impl/codegen/log.h:103
grpc_core::Timeout::Unit::kTenMinutes
@ kTenMinutes
uint16_t
unsigned short uint16_t
Definition: stdint-msvc2008.h:79
grpc_core::Timeout::Unit::kHundredMilliseconds
@ kHundredMilliseconds
grpc_core::Timeout::value_
uint16_t value_
Definition: timeout_encoding.h:64
grpc_core
Definition: call_metric_recorder.h:31
grpc_core::Timeout::Unit::kHundredMinutes
@ kHundredMinutes
grpc_core::Slice
Definition: src/core/lib/slice/slice.h:282
buf
voidpf void * buf
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:136
grpc_core::Timeout::Unit::kSeconds
@ kSeconds
time.h
a
int a
Definition: abseil-cpp/absl/container/internal/hash_policy_traits_test.cc:88
xds_manager.p
p
Definition: xds_manager.py:60
grpc_core::Timeout::Encode
Slice Encode() const
Definition: timeout_encoding.cc:91
grpc_core::Timeout::FromMinutes
static Timeout FromMinutes(int64_t minutes)
Definition: timeout_encoding.cc:200
uint8_t
unsigned char uint8_t
Definition: stdint-msvc2008.h:78
grpc_core::Timeout::Unit::kTenSeconds
@ kTenSeconds
grpc_core::Timeout::FromHours
static Timeout FromHours(int64_t hours)
Definition: timeout_encoding.cc:220
grpc_core::Timeout::FromDuration
static Timeout FromDuration(Duration duration)
Definition: timeout_encoding.cc:47
grpc_core::Timeout
Definition: timeout_encoding.h:33
timeout_encoding.h
grpc_core::Timeout::Unit::kMilliseconds
@ kMilliseconds
gen_server_registered_method_bad_client_test_body.text
def text
Definition: gen_server_registered_method_bad_client_test_body.py:50
end
char * end
Definition: abseil-cpp/absl/strings/internal/str_format/float_conversion.cc:1008
int64_t
signed __int64 int64_t
Definition: stdint-msvc2008.h:89
grpc_core::Timeout::Unit::kNanoseconds
@ kNanoseconds
grpc_core::slice_detail::CopyConstructors< Slice >::FromCopiedBuffer
static Slice FromCopiedBuffer(const char *p, size_t len)
Definition: src/core/lib/slice/slice.h:182
grpc_core::Timeout::Timeout
Timeout(uint16_t value, Unit unit)
Definition: timeout_encoding.h:57
grpc_core::Timeout::Unit::kTenMilliseconds
@ kTenMilliseconds
absl::optional
Definition: abseil-cpp/absl/types/internal/optional.h:61
x
int x
Definition: bloaty/third_party/googletest/googlemock/test/gmock-matchers_test.cc:3610
GPR_UNREACHABLE_CODE
#define GPR_UNREACHABLE_CODE(STATEMENT)
Definition: impl/codegen/port_platform.h:652
b
uint64_t b
Definition: abseil-cpp/absl/container/internal/layout_test.cc:53
n
int n
Definition: abseil-cpp/absl/container/btree_test.cc:1080
grpc_core::Duration::NegativeInfinity
static constexpr Duration NegativeInfinity()
Definition: src/core/lib/gprpp/time.h:135
GPR_NS_PER_MS
#define GPR_NS_PER_MS
Definition: include/grpc/support/time.h:42
value
const char * value
Definition: hpack_parser_table.cc:165
grpc_core::Duration::Zero
static constexpr Duration Zero()
Definition: src/core/lib/gprpp/time.h:130
grpc_core::Timeout::Unit::kMinutes
@ kMinutes
grpc_core::Duration::Milliseconds
static constexpr Duration Milliseconds(int64_t millis)
Definition: src/core/lib/gprpp/time.h:155
grpc_core::Duration::millis
constexpr int64_t millis() const
Definition: src/core/lib/gprpp/time.h:208
GPR_US_PER_MS
#define GPR_US_PER_MS
Definition: include/grpc/support/time.h:44
grpc_core::Timeout::FromMillis
static Timeout FromMillis(int64_t millis)
Definition: timeout_encoding.cc:165
grpc_core::Timeout::AsDuration
Duration AsDuration() const
Definition: timeout_encoding.cc:62
grpc_core::Duration::Seconds
static constexpr Duration Seconds(int64_t seconds)
Definition: src/core/lib/gprpp/time.h:151
grpc_core::Timeout::Unit::kHours
@ kHours
grpc_core::Timeout::FromSeconds
static Timeout FromSeconds(int64_t seconds)
Definition: timeout_encoding.cc:180
grpc_core::Duration
Definition: src/core/lib/gprpp/time.h:122
int32_t
signed int int32_t
Definition: stdint-msvc2008.h:77
ABSL_FALLTHROUGH_INTENDED
#define ABSL_FALLTHROUGH_INTENDED
Definition: abseil-cpp/absl/base/attributes.h:641
grpc_core::Timeout::unit_
Unit unit_
Definition: timeout_encoding.h:65
timeout
uv_timer_t timeout
Definition: libuv/docs/code/uvwget/main.c:9
grpc_core::Duration::Infinity
static constexpr Duration Infinity()
Definition: src/core/lib/gprpp/time.h:139
grpc_core::Timeout::RatioVersus
double RatioVersus(Timeout other) const
Definition: timeout_encoding.cc:51
grpc_core::Duration::Minutes
static constexpr Duration Minutes(int64_t minutes)
Definition: src/core/lib/gprpp/time.h:147
port_platform.h


grpc
Author(s):
autogenerated on Thu Mar 13 2025 03:01:39