YugabyteDB (2.13.1.0-b60, 21121d69985fbf76aa6958d8f04a9bfa936293b5)

Coverage Report

Created: 2022-03-22 16:43

/Users/deen/code/yugabyte-db/src/yb/docdb/intent.h
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
14
#ifndef YB_DOCDB_INTENT_H_
15
#define YB_DOCDB_INTENT_H_
16
17
#include "yb/common/doc_hybrid_time.h"
18
#include "yb/common/transaction.h"
19
20
#include "yb/docdb/docdb_fwd.h"
21
22
namespace yb {
23
namespace docdb {
24
25
// "Intent types" are used for single-tablet operations and cross-shard transactions. For example,
26
// multiple write-only operations don't need to conflict. However, if one operation is a
27
// read-modify-write snapshot isolation operation, then a write-only operation cannot proceed in
28
// parallel with it. Conflicts between intent types are handled according to the conflict matrix at
29
// https://goo.gl/Wbc663.
30
31
// "Weak" intents are obtained for parent nodes of a node that is a transaction is working with.
32
// E.g. if we're writing "a.b.c", we'll obtain weak write intents on "a" and "a.b", but a strong
33
// write intent on "a.b.c".
34
constexpr int kWeakIntentFlag         = 0b000;
35
36
// "Strong" intents are obtained on the node that an operation is working with. See the example
37
// above.
38
constexpr int kStrongIntentFlag       = 0b010;
39
40
constexpr int kReadIntentFlag         = 0b000;
41
constexpr int kWriteIntentFlag        = 0b001;
42
43
// We put weak intents before strong intents to be able to skip weak intents while checking for
44
// conflicts.
45
//
46
// This was not always the case.
47
// kObsoleteIntentTypeSet corresponds to intent type set values stored in such a way that
48
// strong/weak and read/write bits are swapped compared to the current format.
49
YB_DEFINE_ENUM(IntentType,
50
    ((kWeakRead,      kWeakIntentFlag |  kReadIntentFlag))
51
    ((kWeakWrite,     kWeakIntentFlag | kWriteIntentFlag))
52
    ((kStrongRead,  kStrongIntentFlag |  kReadIntentFlag))
53
    ((kStrongWrite, kStrongIntentFlag | kWriteIntentFlag))
54
);
55
56
constexpr int kIntentTypeSetMapSize = 1 << kIntentTypeMapSize;
57
typedef EnumBitSet<IntentType> IntentTypeSet;
58
59
// DecodeIntentKey result.
60
// intent_prefix - intent prefix (SubDocKey (no HT)).
61
struct DecodedIntentKey {
62
  Slice intent_prefix;
63
  IntentTypeSet intent_types;
64
  DocHybridTime doc_ht;
65
66
0
  std::string ToString() const {
67
0
    return Format("{ intent_prefix: $0 intent_types: $1 doc_ht: $2 }",
68
0
                  intent_prefix.ToDebugHexString(), intent_types, doc_ht);
69
0
  }
70
};
71
72
0
inline std::ostream& operator<<(std::ostream& out, const DecodedIntentKey& decoded_intent_key) {
73
0
  return out << decoded_intent_key.ToString();
74
0
}
75
76
// Decodes intent RocksDB key.
77
Result<DecodedIntentKey> DecodeIntentKey(const Slice &encoded_intent_key);
78
79
struct DecodedIntentValue {
80
  // Decoded transaction_id. Nil() value can mean that the transaction_id was not decoded, but not
81
  // necessarily that it was not present.
82
  TransactionId transaction_id = TransactionId::Nil();
83
  // Subtransaction id or defaults to kMinSubtransactionId.
84
  SubTransactionId subtransaction_id;
85
  // Decoded write id.
86
  IntraTxnWriteId write_id;
87
  // The rest of the data after write id.
88
  Slice body;
89
};
90
91
// Decode intent RocksDB value.
92
// encoded_intent_value - input intent value to decode.
93
// transaction_id_slice - input transaction id (to double-check with transaction id in value). If
94
//                        empty, decode TransactionId into returned result instead.
95
// Returned DecodedIntentValue will have a Nil transaction_id unless transaction_id_slice was
96
// non-null.
97
Result<DecodedIntentValue> DecodeIntentValue(
98
    const Slice& encoded_intent_value, const Slice* transaction_id_slice = nullptr,
99
    bool has_strong_intent = true);
100
101
// Decodes transaction ID from intent value. Consumes it from intent_value slice.
102
Result<TransactionId> DecodeTransactionIdFromIntentValue(Slice* intent_value);
103
104
IntentTypeSet GetStrongIntentTypeSet(
105
    IsolationLevel level, OperationKind operation_kind, RowMarkType row_mark);
106
107
174M
inline IntentTypeSet StrongToWeak(IntentTypeSet inp) {
108
174M
  IntentTypeSet result(inp.ToUIntPtr() >> kStrongIntentFlag);
109
174M
  DCHECK((inp & result).None());
110
174M
  return result;
111
174M
}
112
113
0
inline IntentTypeSet WeakToStrong(IntentTypeSet inp) {
114
0
  IntentTypeSet result(inp.ToUIntPtr() << kStrongIntentFlag);
115
0
  DCHECK((inp & result).None());
116
0
  return result;
117
0
}
118
119
bool HasStrong(IntentTypeSet inp);
120
121
IntentTypeSet ObsoleteIntentTypeToSet(uint8_t obsolete_intent_type);
122
IntentTypeSet ObsoleteIntentTypeSetToNew(uint8_t obsolete_intent_type_set);
123
124
// Returns true if ch is value type of one of intent types, obsolete or not.
125
bool IntentValueType(char ch);
126
127
}  // namespace docdb
128
}  // namespace yb
129
130
#endif  // YB_DOCDB_INTENT_H_