1 /*
2 Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
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 <SimpleProperties.hpp>
26 #include "LongSignal.hpp"
27 #include "LongSignalImpl.hpp"
28 #include "SimulatedBlock.hpp"
29
30 #define JAM_FILE_ID 224
31
32
SimplePropertiesSectionReader(struct SegmentedSectionPtr & ptr,class SectionSegmentPool & pool)33 SimplePropertiesSectionReader::SimplePropertiesSectionReader
34 (struct SegmentedSectionPtr & ptr, class SectionSegmentPool & pool)
35 : m_pool(pool)
36 {
37 if(ptr.p == 0){
38 m_pos = 0;
39 m_len = 0;
40 m_head = 0;
41 m_currentSegment = 0;
42 } else {
43 m_pos = 0;
44 m_len = ptr.p->m_sz;
45 m_head = ptr.p;
46 m_currentSegment = ptr.p;
47 }
48 first();
49 }
50
51 void
reset()52 SimplePropertiesSectionReader::reset(){
53 m_pos = 0;
54 m_currentSegment = m_head;
55 }
56
57 bool
step(Uint32 len)58 SimplePropertiesSectionReader::step(Uint32 len){
59 if(m_pos + len >= m_len) {
60 m_pos++;
61 return false;
62 }
63 while(len > SectionSegment::DataLength){
64 m_currentSegment = m_pool.getPtr(m_currentSegment->m_nextSegment);
65
66 len -= SectionSegment::DataLength;
67 m_pos += SectionSegment::DataLength;
68 }
69
70 Uint32 ind = m_pos % SectionSegment::DataLength;
71 while(len > 0){
72 len--;
73 m_pos++;
74
75 ind++;
76 if(ind == SectionSegment::DataLength){
77 ind = 0;
78 m_currentSegment = m_pool.getPtr(m_currentSegment->m_nextSegment);
79 }
80 }
81 return true;
82 }
83
84 bool
getWord(Uint32 * dst)85 SimplePropertiesSectionReader::getWord(Uint32 * dst){
86 if (peekWord(dst)) {
87 step(1);
88 return true;
89 }
90 return false;
91 }
92
93 bool
peekWord(Uint32 * dst) const94 SimplePropertiesSectionReader::peekWord(Uint32 * dst) const {
95 if(m_pos < m_len){
96 Uint32 ind = m_pos % SectionSegment::DataLength;
97 * dst = m_currentSegment->theData[ind];
98 return true;
99 }
100 return false;
101 }
102
103 bool
peekWords(Uint32 * dst,Uint32 len) const104 SimplePropertiesSectionReader::peekWords(Uint32 * dst, Uint32 len) const {
105 if(m_pos + len > m_len){
106 return false;
107 }
108 Uint32 ind = (m_pos % SectionSegment::DataLength);
109 Uint32 left = (SectionSegment::DataLength - ind);
110 SectionSegment * p = m_currentSegment;
111
112 while(len > left){
113 memcpy(dst, &p->theData[ind], 4 * left);
114 dst += left;
115 len -= left;
116 ind = 0;
117 left = SectionSegment::DataLength;
118 p = m_pool.getPtr(p->m_nextSegment);
119 }
120
121 memcpy(dst, &p->theData[ind], 4 * len);
122 return true;
123 }
124
125 bool
getWords(Uint32 * dst,Uint32 len)126 SimplePropertiesSectionReader::getWords(Uint32 * dst, Uint32 len){
127 if(peekWords(dst, len)){
128 step(len);
129 return true;
130 }
131 return false;
132 }
133
SimplePropertiesSectionWriter(class SimulatedBlock & block)134 SimplePropertiesSectionWriter::SimplePropertiesSectionWriter(class SimulatedBlock & block)
135 : m_pool(block.getSectionSegmentPool()), m_block(block)
136 {
137 m_pos = -1;
138 m_head = 0;
139 m_currentSegment = 0;
140 m_prevPtrI = RNIL;
141 reset();
142 }
143
~SimplePropertiesSectionWriter()144 SimplePropertiesSectionWriter::~SimplePropertiesSectionWriter()
145 {
146 release();
147 }
148
149 #ifdef NDBD_MULTITHREADED
150 #define SP_POOL_ARG f_section_lock, *m_block.m_sectionPoolCache,
151 #else
152 #define SP_POOL_ARG
153 #endif
154
155 void
release()156 SimplePropertiesSectionWriter::release()
157 {
158 if (m_head)
159 {
160 if (m_sz)
161 {
162 SegmentedSectionPtr ptr;
163 ptr.p = m_head;
164 ptr.i = m_head->m_lastSegment;
165 ptr.sz = m_sz;
166 m_head->m_sz = m_sz;
167 m_head->m_lastSegment = m_currentSegment->m_lastSegment;
168
169 if((m_pos % SectionSegment::DataLength) == 0){
170 m_pool.release(SP_POOL_ARG m_currentSegment->m_lastSegment);
171 m_head->m_lastSegment = m_prevPtrI;
172 }
173 m_block.release(ptr);
174 }
175 else
176 {
177 m_pool.release(SP_POOL_ARG m_head->m_lastSegment);
178 }
179 }
180 m_pos = -1;
181 m_head = 0;
182 m_currentSegment = 0;
183 m_prevPtrI = RNIL;
184 }
185
186 bool
reset()187 SimplePropertiesSectionWriter::reset()
188 {
189 release();
190 Ptr<SectionSegment> first;
191 if(m_pool.seize(SP_POOL_ARG first)){
192 ;
193 } else {
194 m_pos = -1;
195 m_head = 0;
196 m_currentSegment = 0;
197 m_prevPtrI = RNIL;
198 return false;
199 }
200 m_sz = 0;
201 m_pos = 0;
202 m_head = first.p;
203 m_head->m_lastSegment = first.i;
204 m_currentSegment = first.p;
205 m_prevPtrI = RNIL;
206 return false;
207 }
208
209 bool
putWord(Uint32 val)210 SimplePropertiesSectionWriter::putWord(Uint32 val){
211 return putWords(&val, 1);
212 }
213
214 bool
putWords(const Uint32 * src,Uint32 len)215 SimplePropertiesSectionWriter::putWords(const Uint32 * src, Uint32 len){
216 Uint32 left = SectionSegment::DataLength - m_pos;
217
218 while(len >= left){
219 memcpy(&m_currentSegment->theData[m_pos], src, 4 * left);
220 Ptr<SectionSegment> next;
221 if(m_pool.seize(SP_POOL_ARG next)){
222
223 m_prevPtrI = m_currentSegment->m_lastSegment;
224 m_currentSegment->m_nextSegment = next.i;
225 next.p->m_lastSegment = next.i;
226 m_currentSegment = next.p;
227
228 len -= left;
229 src += left;
230 m_sz += left;
231
232 left = SectionSegment::DataLength;
233 m_pos = 0;
234 } else {
235 abort();
236 return false;
237 }
238 }
239
240 memcpy(&m_currentSegment->theData[m_pos], src, 4 * len);
241 m_sz += len;
242 m_pos += len;
243
244 assert(m_pos < (int)SectionSegment::DataLength);
245
246 return true;
247 }
248
getWordsUsed() const249 Uint32 SimplePropertiesSectionWriter::getWordsUsed() const
250 {
251 return m_sz;
252 }
253
254 void
getPtr(struct SegmentedSectionPtr & dst)255 SimplePropertiesSectionWriter::getPtr(struct SegmentedSectionPtr & dst){
256 // Set last ptr and size
257 if(m_pos >= 0){
258 dst.p = m_head;
259 dst.i = m_head->m_lastSegment;
260 dst.sz = m_sz;
261 m_head->m_sz = m_sz;
262 m_head->m_lastSegment = m_currentSegment->m_lastSegment;
263
264 if((m_pos % SectionSegment::DataLength) == 0){
265 m_pool.release(SP_POOL_ARG m_currentSegment->m_lastSegment);
266 m_head->m_lastSegment = m_prevPtrI;
267 }
268
269 m_sz = 0;
270 m_pos = -1;
271 m_head = m_currentSegment = 0;
272 m_prevPtrI = RNIL;
273 return ;
274 }
275 dst.p = 0;
276 dst.sz = 0;
277 dst.i = RNIL;
278
279 if (m_head)
280 {
281 m_pool.release(SP_POOL_ARG m_head->m_lastSegment);
282 }
283
284 m_sz = 0;
285 m_pos = -1;
286 m_head = m_currentSegment = 0;
287 m_prevPtrI = RNIL;
288 }
289
290 /**
291 * #undef is needed since this file is included by
292 * SimplePropertiesSection_nonmt.cpp and SimplePropertiesSection_mt.cpp
293 */
294 #undef JAM_FILE_ID
295