/Users/deen/code/yugabyte-db/src/yb/docdb/doc_ttl_util.cc
Line | Count | Source (jump to first uncovered line) |
1 | | // Copyright (c) YugaByte, Inc. |
2 | | // |
3 | | // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
4 | | // in compliance with the License. You may obtain a copy of the License at |
5 | | // |
6 | | // http://www.apache.org/licenses/LICENSE-2.0 |
7 | | // |
8 | | // Unless required by applicable law or agreed to in writing, software distributed under the License |
9 | | // is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express |
10 | | // or implied. See the License for the specific language governing permissions and limitations |
11 | | // under the License. |
12 | | // |
13 | | #include "yb/docdb/doc_ttl_util.h" |
14 | | |
15 | | #include "yb/common/schema.h" |
16 | | #include "yb/docdb/value.h" |
17 | | #include "yb/server/hybrid_clock.h" |
18 | | #include "yb/util/monotime.h" |
19 | | |
20 | | using std::string; |
21 | | |
22 | | using yb::HybridTime; |
23 | | |
24 | | namespace yb { |
25 | | namespace docdb { |
26 | | |
27 | | bool HasExpiredTTL(const HybridTime& key_hybrid_time, const MonoDelta &ttl, |
28 | 70.1M | const HybridTime& read_hybrid_time) { |
29 | 70.1M | if (ttl.Equals(ValueControlFields::kMaxTtl) || ttl.Equals(ValueControlFields::kResetTtl)24.2M ) { |
30 | 45.7M | return false; |
31 | 45.7M | } |
32 | 24.3M | return server::HybridClock::CompareHybridClocksToDelta( |
33 | 24.3M | key_hybrid_time, read_hybrid_time, ttl) > 0; |
34 | 70.1M | } |
35 | | |
36 | 81 | bool HasExpiredTTL(const HybridTime& expiration_time, const HybridTime& read_hybrid_time) { |
37 | 81 | if (expiration_time == kNoExpiration || expiration_time == kUseDefaultTTL53 ) { |
38 | 28 | return false; |
39 | 28 | } |
40 | 53 | return expiration_time < read_hybrid_time; |
41 | 81 | } |
42 | | |
43 | 7.57M | const MonoDelta TableTTL(const Schema& schema) { |
44 | | // In this context, a ttl of kMaxTtl indicates that the table has no default TTL. |
45 | 7.57M | MonoDelta ttl = ValueControlFields::kMaxTtl; |
46 | 7.57M | if (schema.table_properties().HasDefaultTimeToLive()) { |
47 | 7.11M | uint64_t default_ttl = schema.table_properties().DefaultTimeToLive(); |
48 | 7.11M | return default_ttl == kResetTTL |
49 | 7.11M | ? ValueControlFields::kMaxTtl175 : MonoDelta::FromMilliseconds(default_ttl)7.11M ; |
50 | 7.11M | } |
51 | 455k | return ttl; |
52 | 7.57M | } |
53 | | |
54 | 1.86M | const MonoDelta ComputeTTL(const MonoDelta& value_ttl, const MonoDelta& default_ttl) { |
55 | 1.86M | MonoDelta ttl; |
56 | | // When encoded with a value, kMaxTtl indicates that table TTL should be used. |
57 | | // If not kMaxTtl, then there is a value-level TTL that we should use instead. |
58 | | // A value of kResetTTL (i.e. 0) indicates the value should not expire, in which |
59 | | // case kMaxTtl (now representing no expiration) is returned. |
60 | 1.86M | if (!value_ttl.Equals(ValueControlFields::kMaxTtl)) { |
61 | 332 | ttl = value_ttl.ToMilliseconds() == kResetTTL ? ValueControlFields::kMaxTtl7 : value_ttl325 ; |
62 | 1.86M | } else { |
63 | 1.86M | ttl = default_ttl; |
64 | 1.86M | } |
65 | 1.86M | return ttl; |
66 | 1.86M | } |
67 | | |
68 | 3 | const MonoDelta ComputeTTL(const MonoDelta& value_ttl, const Schema& schema) { |
69 | 3 | return ComputeTTL(value_ttl, TableTTL(schema)); |
70 | 3 | } |
71 | | |
72 | | const HybridTime FileExpirationFromValueTTL( |
73 | 8.83M | const HybridTime& key_hybrid_time, const MonoDelta& value_ttl) { |
74 | 8.83M | if (value_ttl.Equals(ValueControlFields::kMaxTtl)) { |
75 | 8.82M | return kUseDefaultTTL; |
76 | 8.82M | } else if (3.37k value_ttl.Equals(ValueControlFields::kResetTtl)3.37k ) { |
77 | 13 | return kNoExpiration; |
78 | 13 | } |
79 | 3.35k | auto exp_time = server::HybridClock::AddPhysicalTimeToHybridTime(key_hybrid_time, value_ttl); |
80 | | // Sanity check for overflow, return no expiration if detected. |
81 | 3.35k | if (server::HybridClock::CompareHybridClocksToDelta( |
82 | 3.35k | key_hybrid_time, exp_time, value_ttl) != 0) { |
83 | 2 | return kNoExpiration; |
84 | 2 | } |
85 | 3.35k | return exp_time; |
86 | 3.35k | } |
87 | | |
88 | | const HybridTime MaxExpirationFromValueAndTableTTL(const HybridTime& key_hybrid_time, |
89 | 79 | const MonoDelta& table_ttl, const HybridTime& value_expiry) { |
90 | | // If the max expiration time of values requires the file never expire, |
91 | | // then don't expire the file no matter what. |
92 | 79 | if (value_expiry == kNoExpiration || key_hybrid_time.is_special()64 ) { |
93 | 17 | return kNoExpiration; |
94 | 17 | } |
95 | | // If the table TTL indicates no expiration, then defer to the value expiration. |
96 | | // If the value expiration also indicates to use the table TTL, don't expire the file. |
97 | 62 | if (table_ttl.Equals(ValueControlFields::kMaxTtl)) { |
98 | 23 | return value_expiry == kUseDefaultTTL ? kNoExpiration14 : value_expiry9 ; |
99 | 23 | } |
100 | | |
101 | | // Calculate the expiration time based on table TTL only. |
102 | 39 | auto table_expiry = server::HybridClock::AddPhysicalTimeToHybridTime(key_hybrid_time, table_ttl); |
103 | | // Sanity check for overflow, return no expiration if overflow detected. |
104 | 39 | if (server::HybridClock::CompareHybridClocksToDelta( |
105 | 39 | key_hybrid_time, table_expiry, table_ttl) != 0) { |
106 | 0 | return kNoExpiration; |
107 | 0 | } |
108 | | // Return the greater of the table expiration time and the value expiration time. |
109 | 39 | return value_expiry >= table_expiry ? value_expiry7 : table_expiry32 ; |
110 | 39 | } |
111 | | |
112 | | } // namespace docdb |
113 | | } // namespace yb |