Skip to content

Commit 21e2def

Browse files
lockerkyukhin
authored andcommitted
box: introduce result processor
A convenient helper that is supposed to apply various transformations to a tuple fetched from a space before returning it to the user. Usage: struct result_processor res_proc; result_process_prepare(&res_proc, space); rc = index_get(index, key, part_count, result); result_process(&res_proc, &rc, result); We need to split the procedure into two parts, because index_get and similar methods may yield in case of Vinyl. The 'prepare' method is supposed to pin all data structures needed to process the result in the result_processor struct while the 'process' method is supposed to release them. Currently, the new methods do absolutely nothing. They will be used to convert tuples during space upgrade. NO_DOC=internal NO_TEST=internal NO_CHANGELOG=internal
1 parent e00fd42 commit 21e2def

File tree

3 files changed

+102
-7
lines changed

3 files changed

+102
-7
lines changed

src/box/box.cc

+18-2
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858
#include "vinyl.h"
5959
#include "space.h"
6060
#include "index.h"
61+
#include "result.h"
6162
#include "port.h"
6263
#include "txn.h"
6364
#include "txn_limbo.h"
@@ -297,6 +298,8 @@ box_process_rw(struct request *request, struct space *space,
297298
bool return_tuple = false;
298299
struct txn *txn = in_txn();
299300
bool is_autocommit = txn == NULL;
301+
struct result_processor res_proc;
302+
int rc;
300303
if (is_autocommit && (txn = txn_begin()) == NULL)
301304
return -1;
302305
assert(iproto_type_is_dml(request->type));
@@ -305,14 +308,19 @@ box_process_rw(struct request *request, struct space *space,
305308
goto rollback;
306309
if (txn_begin_stmt(txn, space, request->type) != 0)
307310
goto rollback;
308-
if (space_execute_dml(space, txn, request, &tuple) != 0) {
311+
result_process_prepare(&res_proc, space);
312+
rc = space_execute_dml(space, txn, request, &tuple);
313+
if (result == NULL)
314+
tuple = NULL;
315+
result_process(&res_proc, &rc, &tuple);
316+
if (rc != 0) {
309317
txn_rollback_stmt(txn);
310318
goto rollback;
311319
}
312320
if (result != NULL)
313321
*result = tuple;
314322

315-
return_tuple = result != NULL && tuple != NULL;
323+
return_tuple = tuple != NULL;
316324
if (return_tuple) {
317325
/*
318326
* Pin the tuple locally before the commit,
@@ -2444,7 +2452,10 @@ box_select(uint32_t space_id, uint32_t index_id,
24442452
struct tuple *tuple;
24452453
port_c_create(port);
24462454
while (found < limit) {
2455+
struct result_processor res_proc;
2456+
result_process_prepare(&res_proc, space);
24472457
rc = iterator_next(it, &tuple);
2458+
result_process(&res_proc, &rc, &tuple);
24482459
if (rc != 0 || tuple == NULL)
24492460
break;
24502461
if (offset > 0) {
@@ -2455,6 +2466,11 @@ box_select(uint32_t space_id, uint32_t index_id,
24552466
if (rc != 0)
24562467
break;
24572468
found++;
2469+
/*
2470+
* Refresh the pointer to the space, because the space struct
2471+
* could be freed if the iterator yielded.
2472+
*/
2473+
space = iterator_space(it);
24582474
}
24592475
iterator_delete(it);
24602476

src/box/index.cc

+31-5
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include "schema.h"
3535
#include "user_def.h"
3636
#include "space.h"
37+
#include "result.h"
3738
#include "iproto_constants.h"
3839
#include "txn.h"
3940
#include "rmean.h"
@@ -216,7 +217,11 @@ box_index_random(uint32_t space_id, uint32_t index_id, uint32_t rnd,
216217
if (check_index(space_id, index_id, &space, &index) != 0)
217218
return -1;
218219
/* No tx management, random() is for approximation anyway. */
219-
if (index_random(index, rnd, result) != 0)
220+
struct result_processor res_proc;
221+
result_process_prepare(&res_proc, space);
222+
int rc = index_random(index, rnd, result);
223+
result_process(&res_proc, &rc, result);
224+
if (rc != 0)
220225
return -1;
221226
if (*result != NULL)
222227
tuple_bless(*result);
@@ -247,7 +252,11 @@ box_index_get(uint32_t space_id, uint32_t index_id, const char *key,
247252
struct txn_ro_savepoint svp;
248253
if (txn_begin_ro_stmt(space, &txn, &svp) != 0)
249254
return -1;
250-
if (index_get(index, key, part_count, result) != 0) {
255+
struct result_processor res_proc;
256+
result_process_prepare(&res_proc, space);
257+
int rc = index_get(index, key, part_count, result);
258+
result_process(&res_proc, &rc, result);
259+
if (rc != 0) {
251260
txn_rollback_stmt(txn);
252261
return -1;
253262
}
@@ -284,7 +293,11 @@ box_index_min(uint32_t space_id, uint32_t index_id, const char *key,
284293
struct txn_ro_savepoint svp;
285294
if (txn_begin_ro_stmt(space, &txn, &svp) != 0)
286295
return -1;
287-
if (index_min(index, key, part_count, result) != 0) {
296+
struct result_processor res_proc;
297+
result_process_prepare(&res_proc, space);
298+
int rc = index_min(index, key, part_count, result);
299+
result_process(&res_proc, &rc, result);
300+
if (rc != 0) {
288301
txn_rollback_stmt(txn);
289302
return -1;
290303
}
@@ -319,7 +332,11 @@ box_index_max(uint32_t space_id, uint32_t index_id, const char *key,
319332
struct txn_ro_savepoint svp;
320333
if (txn_begin_ro_stmt(space, &txn, &svp) != 0)
321334
return -1;
322-
if (index_max(index, key, part_count, result) != 0) {
335+
struct result_processor res_proc;
336+
result_process_prepare(&res_proc, space);
337+
int rc = index_max(index, key, part_count, result);
338+
result_process(&res_proc, &rc, result);
339+
if (rc != 0) {
323340
txn_rollback_stmt(txn);
324341
return -1;
325342
}
@@ -408,7 +425,16 @@ int
408425
box_iterator_next(box_iterator_t *itr, box_tuple_t **result)
409426
{
410427
assert(result != NULL);
411-
if (iterator_next(itr, result) != 0)
428+
struct space *space = iterator_space(itr);
429+
if (space == NULL) {
430+
*result = NULL;
431+
return 0;
432+
}
433+
struct result_processor res_proc;
434+
result_process_prepare(&res_proc, space);
435+
int rc = iterator_next(itr, result);
436+
result_process(&res_proc, &rc, result);
437+
if (rc != 0)
412438
return -1;
413439
if (*result != NULL)
414440
tuple_bless(*result);

src/box/result.h

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
* SPDX-License-Identifier: BSD-2-Clause
3+
*
4+
* Copyright 2010-2022, Tarantool AUTHORS, please see AUTHORS file.
5+
*/
6+
#pragma once
7+
8+
struct space;
9+
struct tuple;
10+
11+
#if defined(__cplusplus)
12+
extern "C" {
13+
#endif /* defined(__cplusplus) */
14+
15+
/**
16+
* Helpers that apply various transformations to tuples fetched from a space.
17+
* The procedure is split in two parts, because the read operation may yield,
18+
* which opens a time window during which the space struct can be deleted.
19+
* The 'prepare' phase is supposed to reference and store in result_processor
20+
* all data structures needed to apply transforamtions.
21+
*
22+
* Used by box methods that read tuples from a space and return them to
23+
* the user like this:
24+
*
25+
* struct result_processor res_proc;
26+
* result_process_prepare(&res_proc, space);
27+
* rc = index_get(index, key, part_count, result);
28+
* result_process(&res_proc, &rc, result);
29+
*
30+
* Note, if result_process_prepare() was called, then result_process()
31+
* must be called as well, because it may need to free some resources.
32+
*/
33+
struct result_processor {
34+
};
35+
36+
static inline void
37+
result_process_prepare(struct result_processor *p, struct space *space)
38+
{
39+
(void)p;
40+
(void)space;
41+
}
42+
43+
static inline void
44+
result_process(struct result_processor *p, int *rc, struct tuple **result)
45+
{
46+
(void)p;
47+
(void)rc;
48+
(void)result;
49+
}
50+
51+
#if defined(__cplusplus)
52+
} /* extern "C" */
53+
#endif /* defined(__cplusplus) */

0 commit comments

Comments
 (0)