MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SimplePropertiesSection.cpp
1 /*
2  Copyright (C) 2003-2006, 2008 MySQL AB, 2008 Sun Microsystems, Inc.
3  All rights reserved. Use is subject to license terms.
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; version 2 of the License.
8 
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with this program; if not, write to the Free Software
16  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18 
19 #include <SimpleProperties.hpp>
20 #include <TransporterDefinitions.hpp>
21 #include "LongSignal.hpp"
22 #include "LongSignalImpl.hpp"
23 #include "SimulatedBlock.hpp"
24 
25 SimplePropertiesSectionReader::SimplePropertiesSectionReader
26 (struct SegmentedSectionPtr & ptr, class SectionSegmentPool & pool)
27  : m_pool(pool)
28 {
29  if(ptr.p == 0){
30  m_pos = 0;
31  m_len = 0;
32  m_head = 0;
33  m_currentSegment = 0;
34  } else {
35  m_pos = 0;
36  m_len = ptr.p->m_sz;
37  m_head = ptr.p;
38  m_currentSegment = ptr.p;
39  }
40  first();
41 }
42 
43 void
44 SimplePropertiesSectionReader::reset(){
45  m_pos = 0;
46  m_currentSegment = m_head;
47 }
48 
49 bool
50 SimplePropertiesSectionReader::step(Uint32 len){
51  if(m_pos + len >= m_len) {
52  m_pos++;
53  return false;
54  }
55  while(len > SectionSegment::DataLength){
56  m_currentSegment = m_pool.getPtr(m_currentSegment->m_nextSegment);
57 
58  len -= SectionSegment::DataLength;
59  m_pos += SectionSegment::DataLength;
60  }
61 
62  Uint32 ind = m_pos % SectionSegment::DataLength;
63  while(len > 0){
64  len--;
65  m_pos++;
66 
67  ind++;
68  if(ind == SectionSegment::DataLength){
69  ind = 0;
70  m_currentSegment = m_pool.getPtr(m_currentSegment->m_nextSegment);
71  }
72  }
73  return true;
74 }
75 
76 bool
77 SimplePropertiesSectionReader::getWord(Uint32 * dst){
78  if (peekWord(dst)) {
79  step(1);
80  return true;
81  }
82  return false;
83 }
84 
85 bool
86 SimplePropertiesSectionReader::peekWord(Uint32 * dst) const {
87  if(m_pos < m_len){
88  Uint32 ind = m_pos % SectionSegment::DataLength;
89  * dst = m_currentSegment->theData[ind];
90  return true;
91  }
92  return false;
93 }
94 
95 bool
96 SimplePropertiesSectionReader::peekWords(Uint32 * dst, Uint32 len) const {
97  if(m_pos + len > m_len){
98  return false;
99  }
100  Uint32 ind = (m_pos % SectionSegment::DataLength);
101  Uint32 left = (SectionSegment::DataLength - ind);
102  SectionSegment * p = m_currentSegment;
103 
104  while(len > left){
105  memcpy(dst, &p->theData[ind], 4 * left);
106  dst += left;
107  len -= left;
108  ind = 0;
109  left = SectionSegment::DataLength;
110  p = m_pool.getPtr(p->m_nextSegment);
111  }
112 
113  memcpy(dst, &p->theData[ind], 4 * len);
114  return true;
115 }
116 
117 bool
118 SimplePropertiesSectionReader::getWords(Uint32 * dst, Uint32 len){
119  if(peekWords(dst, len)){
120  step(len);
121  return true;
122  }
123  return false;
124 }
125 
126 SimplePropertiesSectionWriter::SimplePropertiesSectionWriter(class SimulatedBlock & block)
127  : m_pool(block.getSectionSegmentPool()), m_block(block)
128 {
129  m_pos = -1;
130  m_head = 0;
131  m_currentSegment = 0;
132  m_prevPtrI = RNIL;
133  reset();
134 }
135 
136 SimplePropertiesSectionWriter::~SimplePropertiesSectionWriter()
137 {
138  release();
139 }
140 
141 #ifdef NDBD_MULTITHREADED
142 #define SP_POOL_ARG f_section_lock, *m_block.m_sectionPoolCache,
143 #else
144 #define SP_POOL_ARG
145 #endif
146 
147 void
148 SimplePropertiesSectionWriter::release()
149 {
150  if (m_head)
151  {
152  if (m_sz)
153  {
155  ptr.p = m_head;
156  ptr.i = m_head->m_lastSegment;
157  ptr.sz = m_sz;
158  m_head->m_sz = m_sz;
159  m_head->m_lastSegment = m_currentSegment->m_lastSegment;
160 
161  if((m_pos % SectionSegment::DataLength) == 0){
162  m_pool.release(SP_POOL_ARG m_currentSegment->m_lastSegment);
163  m_head->m_lastSegment = m_prevPtrI;
164  }
165  m_block.release(ptr);
166  }
167  else
168  {
169  m_pool.release(SP_POOL_ARG m_head->m_lastSegment);
170  }
171  }
172  m_pos = -1;
173  m_head = 0;
174  m_currentSegment = 0;
175  m_prevPtrI = RNIL;
176 }
177 
178 bool
179 SimplePropertiesSectionWriter::reset()
180 {
181  release();
182  Ptr<SectionSegment> first;
183  if(m_pool.seize(SP_POOL_ARG first)){
184  ;
185  } else {
186  m_pos = -1;
187  m_head = 0;
188  m_currentSegment = 0;
189  m_prevPtrI = RNIL;
190  return false;
191  }
192  m_sz = 0;
193  m_pos = 0;
194  m_head = first.p;
195  m_head->m_lastSegment = first.i;
196  m_currentSegment = first.p;
197  m_prevPtrI = RNIL;
198  return false;
199 }
200 
201 bool
202 SimplePropertiesSectionWriter::putWord(Uint32 val){
203  return putWords(&val, 1);
204 }
205 
206 bool
207 SimplePropertiesSectionWriter::putWords(const Uint32 * src, Uint32 len){
208  Uint32 left = SectionSegment::DataLength - m_pos;
209 
210  while(len >= left){
211  memcpy(&m_currentSegment->theData[m_pos], src, 4 * left);
212  Ptr<SectionSegment> next;
213  if(m_pool.seize(SP_POOL_ARG next)){
214 
215  m_prevPtrI = m_currentSegment->m_lastSegment;
216  m_currentSegment->m_nextSegment = next.i;
217  next.p->m_lastSegment = next.i;
218  m_currentSegment = next.p;
219 
220  len -= left;
221  src += left;
222  m_sz += left;
223 
224  left = SectionSegment::DataLength;
225  m_pos = 0;
226  } else {
227  abort();
228  return false;
229  }
230  }
231 
232  memcpy(&m_currentSegment->theData[m_pos], src, 4 * len);
233  m_sz += len;
234  m_pos += len;
235 
236  assert(m_pos < (int)SectionSegment::DataLength);
237 
238  return true;
239 }
240 
241 Uint32 SimplePropertiesSectionWriter::getWordsUsed() const
242 {
243  return m_sz;
244 }
245 
246 void
248  // Set last ptr and size
249  if(m_pos >= 0){
250  dst.p = m_head;
251  dst.i = m_head->m_lastSegment;
252  dst.sz = m_sz;
253  m_head->m_sz = m_sz;
254  m_head->m_lastSegment = m_currentSegment->m_lastSegment;
255 
256  if((m_pos % SectionSegment::DataLength) == 0){
257  m_pool.release(SP_POOL_ARG m_currentSegment->m_lastSegment);
258  m_head->m_lastSegment = m_prevPtrI;
259  }
260 
261  m_sz = 0;
262  m_pos = -1;
263  m_head = m_currentSegment = 0;
264  m_prevPtrI = RNIL;
265  return ;
266  }
267  dst.p = 0;
268  dst.sz = 0;
269  dst.i = RNIL;
270 
271  if (m_head)
272  {
273  m_pool.release(SP_POOL_ARG m_head->m_lastSegment);
274  }
275 
276  m_sz = 0;
277  m_pos = -1;
278  m_head = m_currentSegment = 0;
279  m_prevPtrI = RNIL;
280 }