1/*
2 * rw_utils_ce.c
3 *
4 * Copyright (C) 2016-2018 Aerospike, Inc.
5 *
6 * Portions may be licensed to Aerospike, Inc. under one or more contributor
7 * license agreements.
8 *
9 * This program is free software: you can redistribute it and/or modify it under
10 * the terms of the GNU Affero General Public License as published by the Free
11 * Software Foundation, either version 3 of the License, or (at your option) any
12 * later version.
13 *
14 * This program is distributed in the hope that it will be useful, but WITHOUT
15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16 * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
17 * details.
18 *
19 * You should have received a copy of the GNU Affero General Public License
20 * along with this program. If not, see http://www.gnu.org/licenses/
21 */
22
23//==========================================================
24// Includes.
25//
26
27#include "transaction/rw_utils.h"
28
29#include <stdbool.h>
30#include <stdint.h>
31
32#include "fault.h"
33#include "msg.h"
34
35#include "base/datamodel.h"
36#include "base/index.h"
37#include "base/proto.h"
38#include "base/transaction.h"
39#include "base/udf_record.h"
40#include "storage/storage.h"
41#include "transaction/rw_request.h"
42#include "transaction/udf.h"
43
44
45//==========================================================
46// Public API.
47//
48
49bool
50validate_delete_durability(as_transaction* tr)
51{
52 return true;
53}
54
55
56int
57repl_state_check(as_record* r, as_transaction* tr)
58{
59 return 0;
60}
61
62
63void
64will_replicate(as_record* r, as_namespace* ns)
65{
66}
67
68
69bool
70insufficient_replica_destinations(const as_namespace* ns, uint32_t n_dests)
71{
72 return false;
73}
74
75
76void
77finished_replicated(as_transaction* tr)
78{
79}
80
81
82void
83finished_not_replicated(rw_request* rw)
84{
85}
86
87
88bool
89generation_check(const as_record* r, const as_msg* m, const as_namespace* ns)
90{
91 if ((m->info2 & AS_MSG_INFO2_GENERATION) != 0) {
92 return m->generation == r->generation;
93 }
94
95 if ((m->info2 & AS_MSG_INFO2_GENERATION_GT) != 0) {
96 return m->generation > r->generation;
97 }
98
99 return true; // no generation requirement
100}
101
102
103int
104set_delete_durablility(const as_transaction* tr, as_storage_rd* rd)
105{
106 if (as_transaction_is_durable_delete(tr)) {
107 cf_warning(AS_RW, "durable delete is an enterprise feature");
108 return AS_ERR_ENTERPRISE_ONLY;
109 }
110
111 return 0;
112}
113
114
115//==========================================================
116// Private API - for enterprise separation only.
117//
118
119bool
120create_only_check(const as_record* r, const as_msg* m)
121{
122 // Ok (return true) if no requirement.
123 return (m->info2 & AS_MSG_INFO2_CREATE_ONLY) == 0;
124}
125
126
127void
128write_delete_record(as_record* r, as_index_tree* tree)
129{
130 as_index_delete(tree, &r->keyd);
131}
132
133
134udf_optype
135udf_finish_delete(udf_record* urecord)
136{
137 return (urecord->flag & UDF_RECORD_FLAG_PREEXISTS) != 0 ?
138 UDF_OPTYPE_DELETE : UDF_OPTYPE_NONE;
139}
140
141
142uint32_t
143dup_res_pack_repl_state_info(const as_record* r, as_namespace* ns)
144{
145 return 0;
146}
147
148
149uint32_t
150dup_res_pack_info(const as_record* r, as_namespace* ns)
151{
152 return 0;
153}
154
155
156bool
157dup_res_should_retry_transaction(rw_request* rw, uint32_t result_code)
158{
159 // TODO - JUMP - can get this from 3.14.x nodes or older - retry if so.
160 return result_code == AS_ERR_CLUSTER_KEY_MISMATCH;
161}
162
163
164void
165dup_res_handle_tie(rw_request* rw, const msg* m, uint32_t result_code)
166{
167}
168
169
170void
171apply_if_tie(rw_request* rw)
172{
173}
174
175
176void
177dup_res_translate_result_code(rw_request* rw)
178{
179 rw->result_code = AS_OK;
180}
181
182
183bool
184dup_res_ignore_pickle(const uint8_t* buf, uint32_t info)
185{
186 return as_record_pickle_is_binless(buf);
187}
188
189
190void
191dup_res_init_repl_state(as_remote_record* rr, uint32_t info)
192{
193}
194
195
196void
197repl_write_flag_pickle(const as_transaction* tr, const uint8_t* buf,
198 uint32_t* info)
199{
200 // Do nothing.
201}
202
203
204bool
205repl_write_pickle_is_drop(const uint8_t* buf, uint32_t info)
206{
207 return as_record_pickle_is_binless(buf);
208}
209
210
211void
212repl_write_init_repl_state(as_remote_record* rr, bool from_replica)
213{
214}
215
216
217conflict_resolution_pol
218repl_write_conflict_resolution_policy(const as_namespace* ns)
219{
220 return AS_NAMESPACE_CONFLICT_RESOLUTION_POLICY_LAST_UPDATE_TIME;
221}
222
223
224bool
225repl_write_should_retransmit_replicas(rw_request* rw, uint32_t result_code)
226{
227 switch (result_code) {
228 case AS_ERR_CLUSTER_KEY_MISMATCH:
229 rw->xmit_ms = 0; // force retransmit on next cycle
230 return true;
231 default:
232 return false;
233 }
234}
235
236
237void
238repl_write_send_confirmation(rw_request* rw)
239{
240}
241
242
243void
244repl_write_handle_confirmation(msg* m)
245{
246}
247
248
249int
250record_replace_check(as_record* r, as_namespace* ns)
251{
252 return 0;
253}
254
255
256void
257record_replaced(as_record* r, as_remote_record* rr)
258{
259}
260