1/* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2// vim: ft=cpp:expandtab:ts=8:sw=4:softtabstop=4:
3#ident "$Id$"
4/*======
5This file is part of PerconaFT.
6
7
8Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
9
10 PerconaFT is free software: you can redistribute it and/or modify
11 it under the terms of the GNU General Public License, version 2,
12 as published by the Free Software Foundation.
13
14 PerconaFT is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with PerconaFT. If not, see <http://www.gnu.org/licenses/>.
21
22----------------------------------------
23
24 PerconaFT is free software: you can redistribute it and/or modify
25 it under the terms of the GNU Affero General Public License, version 3,
26 as published by the Free Software Foundation.
27
28 PerconaFT is distributed in the hope that it will be useful,
29 but WITHOUT ANY WARRANTY; without even the implied warranty of
30 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31 GNU Affero General Public License for more details.
32
33 You should have received a copy of the GNU Affero General Public License
34 along with PerconaFT. If not, see <http://www.gnu.org/licenses/>.
35======= */
36
37#ident "Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved."
38
39/* The purpose of this file is to provide access to the ft_msg,
40 * which is the ephemeral version of the messages that lives in
41 * a message buffer.
42 */
43#pragma once
44
45#include <db.h>
46
47#include "portability/toku_assert.h"
48#include "portability/toku_stdint.h"
49
50#include "ft/txn/xids.h"
51
52// Message Sequence Number (MSN)
53typedef struct __toku_msn { uint64_t msn; } MSN;
54
55// dummy used for message construction, to be filled in when msg is applied to tree
56static const MSN ZERO_MSN = { .msn = 0 };
57
58// first 2^62 values reserved for messages created before Dr. No (for upgrade)
59static const MSN MIN_MSN = { .msn = 1ULL << 62 };
60static const MSN MAX_MSN = { .msn = UINT64_MAX };
61
62/* tree command types */
63enum ft_msg_type {
64 FT_NONE = 0,
65 FT_INSERT = 1,
66 FT_DELETE_ANY = 2, // Delete any matching key. This used to be called FT_DELETE.
67 //FT_DELETE_BOTH = 3,
68 FT_ABORT_ANY = 4, // Abort any commands on any matching key.
69 //FT_ABORT_BOTH = 5, // Abort commands that match both the key and the value
70 FT_COMMIT_ANY = 6,
71 //FT_COMMIT_BOTH = 7,
72 FT_COMMIT_BROADCAST_ALL = 8, // Broadcast to all leafentries, (commit all transactions).
73 FT_COMMIT_BROADCAST_TXN = 9, // Broadcast to all leafentries, (commit specific transaction).
74 FT_ABORT_BROADCAST_TXN = 10, // Broadcast to all leafentries, (commit specific transaction).
75 FT_INSERT_NO_OVERWRITE = 11,
76 FT_OPTIMIZE = 12, // Broadcast
77 FT_OPTIMIZE_FOR_UPGRADE = 13, // same as FT_OPTIMIZE, but record version number in leafnode
78 FT_UPDATE = 14,
79 FT_UPDATE_BROADCAST_ALL = 15
80};
81
82static inline bool
83ft_msg_type_applies_once(enum ft_msg_type type)
84{
85 bool ret_val;
86 switch (type) {
87 case FT_INSERT_NO_OVERWRITE:
88 case FT_INSERT:
89 case FT_DELETE_ANY:
90 case FT_ABORT_ANY:
91 case FT_COMMIT_ANY:
92 case FT_UPDATE:
93 ret_val = true;
94 break;
95 case FT_COMMIT_BROADCAST_ALL:
96 case FT_COMMIT_BROADCAST_TXN:
97 case FT_ABORT_BROADCAST_TXN:
98 case FT_OPTIMIZE:
99 case FT_OPTIMIZE_FOR_UPGRADE:
100 case FT_UPDATE_BROADCAST_ALL:
101 case FT_NONE:
102 ret_val = false;
103 break;
104 default:
105 assert(false);
106 }
107 return ret_val;
108}
109
110static inline bool
111ft_msg_type_applies_all(enum ft_msg_type type)
112{
113 bool ret_val;
114 switch (type) {
115 case FT_NONE:
116 case FT_INSERT_NO_OVERWRITE:
117 case FT_INSERT:
118 case FT_DELETE_ANY:
119 case FT_ABORT_ANY:
120 case FT_COMMIT_ANY:
121 case FT_UPDATE:
122 ret_val = false;
123 break;
124 case FT_COMMIT_BROADCAST_ALL:
125 case FT_COMMIT_BROADCAST_TXN:
126 case FT_ABORT_BROADCAST_TXN:
127 case FT_OPTIMIZE:
128 case FT_OPTIMIZE_FOR_UPGRADE:
129 case FT_UPDATE_BROADCAST_ALL:
130 ret_val = true;
131 break;
132 default:
133 assert(false);
134 }
135 return ret_val;
136}
137
138static inline bool
139ft_msg_type_does_nothing(enum ft_msg_type type)
140{
141 return (type == FT_NONE);
142}
143
144class ft_msg {
145public:
146 ft_msg(const DBT *key, const DBT *val, enum ft_msg_type t, MSN m, XIDS x);
147
148 enum ft_msg_type type() const;
149
150 MSN msn() const;
151
152 XIDS xids() const;
153
154 const DBT *kdbt() const;
155
156 const DBT *vdbt() const;
157
158 size_t total_size() const;
159
160 void serialize_to_wbuf(struct wbuf *wb, bool is_fresh) const;
161
162 // deserialization goes through a static factory function so the ft msg
163 // API stays completely const and there's no default constructor
164 static ft_msg deserialize_from_rbuf(struct rbuf *rb, XIDS *xids, bool *is_fresh);
165
166 // Version 13/14 messages did not have an msn - so `m' is the MSN
167 // that will be assigned to the message that gets deserialized.
168 static ft_msg deserialize_from_rbuf_v13(struct rbuf *rb, MSN m, XIDS *xids);
169
170private:
171 const DBT _key;
172 const DBT _val;
173 enum ft_msg_type _type;
174 MSN _msn;
175 XIDS _xids;
176};
177
178// For serialize / deserialize
179
180#include "ft/serialize/wbuf.h"
181
182static inline void wbuf_MSN(struct wbuf *wb, MSN msn) {
183 wbuf_ulonglong(wb, msn.msn);
184}
185
186#include "ft/serialize/rbuf.h"
187
188static inline MSN rbuf_MSN(struct rbuf *rb) {
189 MSN msn = { .msn = rbuf_ulonglong(rb) };
190 return msn;
191}
192