1/*
2 * rw_utils.h
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#pragma once
24
25//==========================================================
26// Includes.
27//
28
29#include <stdbool.h>
30#include <stdint.h>
31
32#include "citrusleaf/cf_digest.h"
33
34#include "msg.h"
35#include "node.h"
36
37#include "base/cfg.h"
38#include "base/datamodel.h"
39#include "base/secondary_index.h"
40#include "base/transaction.h"
41#include "base/transaction_policy.h"
42#include "transaction/rw_request.h"
43#include "transaction/udf.h"
44
45
46//==========================================================
47// Forward declarations.
48//
49
50struct as_bin_s;
51struct as_index_s;
52struct as_index_tree_s;
53struct as_msg_s;
54struct as_namespace_s;
55struct as_remote_record_s;
56struct as_storage_rd_s;
57struct as_transaction_s;
58struct predexp_eval_base_s;
59struct rw_request_s;
60struct udf_record_s;
61
62
63//==========================================================
64// Typedefs & constants.
65//
66
67typedef struct index_metadata_s {
68 uint32_t void_time;
69 uint64_t last_update_time;
70 uint16_t generation;
71} index_metadata;
72
73typedef struct now_times_s {
74 uint64_t now_ns;
75 uint64_t now_ms;
76} now_times;
77
78// For now, use only for as_msg record_ttl special values.
79#define TTL_NAMESPACE_DEFAULT 0
80#define TTL_NEVER_EXPIRE ((uint32_t)-1)
81#define TTL_DONT_UPDATE ((uint32_t)-2)
82
83
84//==========================================================
85// Public API.
86//
87
88bool validate_delete_durability(struct as_transaction_s* tr);
89bool xdr_allows_write(struct as_transaction_s* tr);
90void send_rw_messages(struct rw_request_s* rw);
91void send_rw_messages_forget(struct rw_request_s* rw);
92int repl_state_check(struct as_index_s* r, struct as_transaction_s* tr);
93void will_replicate(struct as_index_s* r, struct as_namespace_s* ns);
94bool insufficient_replica_destinations(const struct as_namespace_s* ns, uint32_t n_dests);
95void finished_replicated(struct as_transaction_s* tr);
96void finished_not_replicated(struct rw_request_s* rw);
97bool set_name_check(const struct as_transaction_s* tr, const struct as_index_s* r);
98bool generation_check(const struct as_index_s* r, const struct as_msg_s* m, const struct as_namespace_s* ns);
99int set_set_from_msg(struct as_index_s* r, struct as_namespace_s* ns, struct as_msg_s* m);
100int set_delete_durablility(const struct as_transaction_s* tr, struct as_storage_rd_s* rd);
101int build_predexp_and_filter_meta(const struct as_transaction_s* tr, const struct as_index_s* r, struct predexp_eval_base_s** predexp);
102int predexp_read_and_filter_bins(struct as_storage_rd_s* rd, struct predexp_eval_base_s* predexp);
103bool check_msg_key(struct as_msg_s* m, struct as_storage_rd_s* rd);
104bool get_msg_key(struct as_transaction_s* tr, struct as_storage_rd_s* rd);
105int handle_msg_key(struct as_transaction_s* tr, struct as_storage_rd_s* rd);
106void update_metadata_in_index(struct as_transaction_s* tr, struct as_index_s* r);
107void pickle_all(struct as_storage_rd_s* rd, struct rw_request_s* rw);
108bool write_sindex_update(struct as_namespace_s* ns, const char* set_name, cf_digest* keyd, struct as_bin_s* old_bins, uint32_t n_old_bins, struct as_bin_s* new_bins, uint32_t n_new_bins);
109void record_delete_adjust_sindex(struct as_index_s* r, struct as_namespace_s* ns);
110void delete_adjust_sindex(struct as_storage_rd_s* rd);
111void remove_from_sindex(struct as_namespace_s* ns, const char* set_name, cf_digest* keyd, struct as_bin_s* bins, uint32_t n_bins);
112bool xdr_must_ship_delete(struct as_namespace_s* ns, bool is_xdr_op);
113
114
115// TODO - rename as as_record_... and move to record.c?
116static inline bool
117record_has_sindex(const as_record* r, as_namespace* ns)
118{
119 if (! as_sindex_ns_has_sindex(ns)) {
120 return false;
121 }
122
123 as_set* set = as_namespace_get_record_set(ns, r);
124
125 return set ? set->n_sindexes != 0 : ns->n_setless_sindexes != 0;
126}
127
128
129static inline bool
130respond_on_master_complete(as_transaction* tr)
131{
132 return tr->origin == FROM_CLIENT &&
133 TR_WRITE_COMMIT_LEVEL(tr) == AS_WRITE_COMMIT_LEVEL_MASTER;
134}
135
136
137static inline void
138destroy_stack_bins(as_bin* stack_bins, uint32_t n_bins)
139{
140 for (uint32_t i = 0; i < n_bins; i++) {
141 as_bin_particle_destroy(&stack_bins[i], true);
142 }
143}
144
145
146// Not a nice way to specify a read-all op - dictated by backward compatibility.
147// Note - must check this before checking for normal read op!
148static inline bool
149op_is_read_all(as_msg_op* op, as_msg* m)
150{
151 return op->name_sz == 0 && op->op == AS_MSG_OP_READ &&
152 (m->info1 & AS_MSG_INFO1_GET_ALL) != 0;
153}
154
155
156static inline bool
157is_valid_ttl(uint32_t ttl)
158{
159 // Note - for now, ttl must be as_msg record_ttl.
160 // Note - ttl <= MAX_ALLOWED_TTL includes ttl == TTL_NAMESPACE_DEFAULT.
161 return ttl <= MAX_ALLOWED_TTL ||
162 ttl == TTL_NEVER_EXPIRE || ttl == TTL_DONT_UPDATE;
163}
164
165
166static inline void
167clear_delete_response_metadata(as_transaction* tr)
168{
169 // If write became delete, respond to origin with no metadata.
170 if ((tr->flags & AS_TRANSACTION_FLAG_IS_DELETE) != 0) {
171 tr->generation = 0;
172 tr->void_time = 0;
173 tr->last_update_time = 0;
174 }
175}
176
177
178//==========================================================
179// Private API - for enterprise separation only.
180//
181
182bool create_only_check(const struct as_index_s* r, const struct as_msg_s* m);
183void write_delete_record(struct as_index_s* r, struct as_index_tree_s* tree);
184
185udf_optype udf_finish_delete(struct udf_record_s* urecord);
186
187uint32_t dup_res_pack_repl_state_info(const struct as_index_s* r, struct as_namespace_s* ns);
188uint32_t dup_res_pack_info(const struct as_index_s* r, struct as_namespace_s* ns);
189bool dup_res_should_retry_transaction(struct rw_request_s* rw, uint32_t result_code);
190void dup_res_handle_tie(struct rw_request_s* rw, const msg* m, uint32_t result_code);
191void apply_if_tie(struct rw_request_s* rw);
192void dup_res_translate_result_code(struct rw_request_s* rw);
193bool dup_res_ignore_pickle(const uint8_t* buf, uint32_t info);
194void dup_res_init_repl_state(struct as_remote_record_s* rr, uint32_t info);
195
196void repl_write_flag_pickle(const struct as_transaction_s* tr, const uint8_t* buf, uint32_t* info);
197bool repl_write_pickle_is_drop(const uint8_t* buf, uint32_t info);
198void repl_write_init_repl_state(struct as_remote_record_s* rr, bool from_replica);
199conflict_resolution_pol repl_write_conflict_resolution_policy(const struct as_namespace_s* ns);
200bool repl_write_should_retransmit_replicas(struct rw_request_s* rw, uint32_t result_code);
201void repl_write_send_confirmation(struct rw_request_s* rw);
202void repl_write_handle_confirmation(msg* m);
203
204int record_replace_check(struct as_index_s* r, struct as_namespace_s* ns);
205void record_replaced(struct as_index_s* r, struct as_remote_record_s* rr);
206