1 /*
2 Copyright (c) 2009, 2021, Oracle and/or its affiliates.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License, version 2.0,
6 as published by the Free Software Foundation.
7
8 This program is also distributed with certain software (including
9 but not limited to OpenSSL) that is licensed under separate terms,
10 as designated in a particular file or component or in included license
11 documentation. The authors of MySQL hereby grant you an additional
12 permission to link the program and your derivative works with the
13 separately licensed software that they have included with MySQL.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License, version 2.0, for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 */
24
25 #include "Dbtux.hpp"
26
27 #define JAM_FILE_ID 373
28
29
30 struct mt_BuildIndxCtx
31 {
32 Uint32 indexId;
33 Uint32 tableId;
34 Uint32 fragId;
35 Dbtup* tup_ptr;
36 Dbtux::TuxCtx * tux_ctx_ptr;
37 NdbMutex * alloc_mutex_ptr;
38 };
39
40 Uint32
Dbtux_mt_buildIndexFragment_wrapper_C(void * obj)41 Dbtux_mt_buildIndexFragment_wrapper_C(void * obj)
42 {
43 return Dbtux::mt_buildIndexFragment_wrapper(obj);
44 }
45
46 Uint32
mt_buildIndexFragment_wrapper(void * obj)47 Dbtux::mt_buildIndexFragment_wrapper(void * obj)
48 {
49 mt_BuildIndxReq* req = reinterpret_cast<mt_BuildIndxReq*>(obj);
50 TuxCtx * tux_ctx = reinterpret_cast<TuxCtx*>(req->mem_buffer);
51 {
52 /**
53 * Setup ctx object...
54 */
55 Uint32 * ptr = reinterpret_cast<Uint32*>(req->mem_buffer);
56 ptr += (sizeof(* tux_ctx) + 3) / 4;
57
58 tux_ctx->jamBuffer = getThrJamBuf();
59 tux_ctx->c_searchKey = ptr;
60 ptr += MaxAttrDataSize;
61 tux_ctx->c_entryKey = ptr;
62 ptr += MaxAttrDataSize;
63 tux_ctx->c_dataBuffer = ptr;
64 ptr += MaxAttrDataSize;
65 #ifdef VM_TRACE
66 tux_ctx->c_debugBuffer = (char*)ptr;
67 ptr += (DebugBufferBytes + 3) / 4;
68 #endif
69 if (!(UintPtr(ptr) - UintPtr(req->mem_buffer) <= req->buffer_size))
70 abort();
71 }
72
73 mt_BuildIndxCtx ctx;
74 ctx.indexId = req->indexId;
75 ctx.tableId = req->tableId;
76 ctx.fragId = req->fragId;
77 ctx.tux_ctx_ptr = tux_ctx;
78 ctx.tup_ptr = reinterpret_cast<Dbtup*>(req->tup_ptr);
79
80 Dbtux* tux = reinterpret_cast<Dbtux*>(req->tux_ptr);
81 return tux->mt_buildIndexFragment(&ctx);
82 }
83
84 Uint32 // error code
mt_buildIndexFragment(mt_BuildIndxCtx * req)85 Dbtux::mt_buildIndexFragment(mt_BuildIndxCtx* req)
86 {
87 IndexPtr indexPtr;
88 c_indexPool.getPtr(indexPtr, req->indexId);
89 ndbrequire(indexPtr.p->m_tableId == req->tableId);
90 // get base fragment id and extra bits
91 const Uint32 fragId = req->fragId;
92 // get the fragment
93 FragPtr fragPtr;
94 TuxCtx & ctx = * (TuxCtx*)req->tux_ctx_ptr;
95 findFrag(ctx.jamBuffer, *indexPtr.p, fragId, fragPtr);
96 ndbrequire(fragPtr.i != RNIL);
97 Frag& frag = *fragPtr.p;
98 Local_key pos;
99 Uint32 fragPtrI;
100 int err = req->tup_ptr->mt_scan_init(req->tableId, req->fragId,
101 &pos, &fragPtrI);
102 bool moveNext = false;
103 while (globalData.theRestartFlag != perform_stop &&
104 err == 0 &&
105 (err = req->tup_ptr->mt_scan_next(req->tableId,
106 fragPtrI, &pos, moveNext)) == 0)
107 {
108 moveNext = true;
109
110 // set up search entry
111 TreeEnt ent;
112 ent.m_tupLoc = TupLoc(pos.m_page_no, pos.m_page_idx);
113 ent.m_tupVersion = pos.m_file_no; // used for version
114
115 // set up and read search key
116 KeyData searchKey(indexPtr.p->m_keySpec, false, 0);
117 searchKey.set_buf(ctx.c_searchKey, MaxAttrDataSize << 2);
118 readKeyAttrs(ctx, frag, ent, searchKey, indexPtr.p->m_numAttrs);
119
120 if (unlikely(! indexPtr.p->m_storeNullKey) &&
121 searchKey.get_null_cnt() == indexPtr.p->m_numAttrs) {
122 thrjam(ctx.jamBuffer);
123 continue;
124 }
125
126 TreePos treePos;
127 bool ok = searchToAdd(ctx, frag, searchKey, ent, treePos);
128 ndbrequire(ok);
129
130 /*
131 * At most one new node is inserted in the operation. Pre-allocate
132 * it so that the operation cannot fail.
133 */
134 if (frag.m_freeLoc == NullTupLoc)
135 {
136 thrjam(ctx.jamBuffer);
137 NodeHandle node(frag);
138 err = -(int)allocNode(ctx, node);
139
140 if (err != 0)
141 {
142 break;
143 }
144 frag.m_freeLoc = node.m_loc;
145 ndbrequire(frag.m_freeLoc != NullTupLoc);
146 }
147 treeAdd(ctx, frag, treePos, ent);
148 frag.m_entryCount++;
149 frag.m_entryBytes += searchKey.get_data_len();
150 frag.m_entryOps++;
151 }
152
153 if (err < 0)
154 {
155 return -err;
156 }
157
158 return 0;
159 };
160