244.1.1
by Harrison Fisk
Port Ebay/Google memory storage engine variable width columns. |
1 |
/* Copyright (C) 2000-2002 MySQL AB
|
2 |
Copyright (C) 2008 eBay, Inc
|
|
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 as published by
|
|
6 |
the Free Software Foundation; version 2 of the License.
|
|
7 |
||
8 |
This program is distributed in the hope that it will be useful,
|
|
9 |
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
10 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
11 |
GNU General Public License for more details.
|
|
12 |
||
13 |
You should have received a copy of the GNU General Public License
|
|
14 |
along with this program; if not, write to the Free Software
|
|
15 |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
|
16 |
||
17 |
/* Implements various base record-related functions, such as encode and decode into chunks */
|
|
18 |
||
1130.3.28
by Monty Taylor
Moved heapdef.h and myisamdef.h to *_priv.h for easier filtering for include guard check. |
19 |
#include "heap_priv.h" |
612.2.13
by Monty Taylor
Work on removing global.h from headers that should be installed. |
20 |
|
543
by Monty Taylor
Renamed drizzle_common again. Removed sql_common. (empty) |
21 |
#include <drizzled/common.h> |
244.1.1
by Harrison Fisk
Port Ebay/Google memory storage engine variable width columns. |
22 |
|
612.2.13
by Monty Taylor
Work on removing global.h from headers that should be installed. |
23 |
#include <string.h> |
1067.4.8
by Nathan Williams
Converted all usages of cmin/cmax in plugin directory to std::min/max. |
24 |
#include <algorithm> |
25 |
||
26 |
using namespace std; |
|
1280.1.10
by Monty Taylor
Put everything in drizzled into drizzled namespace. |
27 |
using namespace drizzled; |
244.1.1
by Harrison Fisk
Port Ebay/Google memory storage engine variable width columns. |
28 |
|
29 |
/**
|
|
30 |
Calculate size of the record for the purpose of storing in chunks
|
|
31 |
||
32 |
Walk through the fields of the record and calculates the exact space
|
|
33 |
needed in chunks as well the the total chunk count
|
|
34 |
||
35 |
@param info the hosting table
|
|
36 |
@param record the record in standard unpacked format
|
|
37 |
@param[out] chunk_count the number of chunks needed for this record
|
|
38 |
||
39 |
@return The size of the required storage in bytes
|
|
40 |
*/
|
|
41 |
||
482
by Brian Aker
Remove uint. |
42 |
uint32_t hp_get_encoded_data_length(HP_SHARE *info, const unsigned char *record, uint32_t *chunk_count) |
244.1.1
by Harrison Fisk
Port Ebay/Google memory storage engine variable width columns. |
43 |
{
|
482
by Brian Aker
Remove uint. |
44 |
uint32_t i, dst_offset; |
244.1.1
by Harrison Fisk
Port Ebay/Google memory storage engine variable width columns. |
45 |
|
46 |
dst_offset= info->fixed_data_length; |
|
47 |
||
48 |
if (!info->recordspace.is_variable_size) |
|
49 |
{
|
|
50 |
/* Nothing more to copy */
|
|
51 |
*chunk_count= 1; |
|
52 |
return dst_offset; |
|
53 |
}
|
|
54 |
||
55 |
for (i= info->fixed_column_count; i < info->column_count; i++) |
|
56 |
{
|
|
482
by Brian Aker
Remove uint. |
57 |
uint32_t src_offset, length; |
244.1.1
by Harrison Fisk
Port Ebay/Google memory storage engine variable width columns. |
58 |
|
59 |
HP_COLUMNDEF* column= info->column_defs + i; |
|
60 |
||
61 |
if (column->null_bit) |
|
62 |
{
|
|
63 |
if (record[column->null_pos] & column->null_bit) |
|
64 |
{
|
|
65 |
/* Skip all NULL values */
|
|
66 |
continue; |
|
67 |
}
|
|
68 |
}
|
|
69 |
||
70 |
src_offset= column->offset; |
|
71 |
if (column->type == DRIZZLE_TYPE_VARCHAR) |
|
72 |
{
|
|
482
by Brian Aker
Remove uint. |
73 |
uint32_t pack_length; |
244.1.1
by Harrison Fisk
Port Ebay/Google memory storage engine variable width columns. |
74 |
|
75 |
/* >= 5.0.3 true VARCHAR */
|
|
76 |
||
77 |
pack_length= column->length_bytes; |
|
78 |
length= pack_length + (pack_length == 1 ? |
|
481
by Brian Aker
Remove all of uchar. |
79 |
(uint) *(unsigned char*) (record + src_offset) : uint2korr(record + src_offset)); |
244.1.1
by Harrison Fisk
Port Ebay/Google memory storage engine variable width columns. |
80 |
}
|
81 |
else
|
|
82 |
{
|
|
83 |
length= column->length; |
|
84 |
}
|
|
85 |
||
86 |
dst_offset+= length; |
|
87 |
}
|
|
88 |
||
89 |
*chunk_count= get_chunk_count(&info->recordspace, dst_offset); |
|
90 |
||
91 |
return dst_offset; |
|
92 |
}
|
|
93 |
||
94 |
||
481
by Brian Aker
Remove all of uchar. |
95 |
/*static void dump_chunk(HP_SHARE *info, const unsigned char* curr_chunk)
|
244.1.1
by Harrison Fisk
Port Ebay/Google memory storage engine variable width columns. |
96 |
{
|
482
by Brian Aker
Remove uint. |
97 |
uint32_t i;
|
244.1.1
by Harrison Fisk
Port Ebay/Google memory storage engine variable width columns. |
98 |
fprintf(stdout, "Chunk dump at 0x%lx: ", (long)curr_chunk);
|
99 |
for (i= 0; i < info->chunk_dataspace_length; i++)
|
|
100 |
{
|
|
482
by Brian Aker
Remove uint. |
101 |
uint32_t b= *((unsigned char*)(curr_chunk + i));
|
244.1.1
by Harrison Fisk
Port Ebay/Google memory storage engine variable width columns. |
102 |
if (b < 0x10)
|
103 |
{
|
|
104 |
fprintf(stdout, "0");
|
|
105 |
}
|
|
106 |
fprintf(stdout, "%lx ", (long)b);
|
|
107 |
}
|
|
108 |
fprintf(stdout, ". Next = 0x%lx, Status = %d\n",
|
|
481
by Brian Aker
Remove all of uchar. |
109 |
(long)(*((unsigned char**) (curr_chunk + info->offset_link))),
|
110 |
(uint)(*((unsigned char*) (curr_chunk + info->offset_status))));
|
|
244.1.1
by Harrison Fisk
Port Ebay/Google memory storage engine variable width columns. |
111 |
}*/
|
112 |
||
113 |
||
114 |
/**
|
|
115 |
Encodes or compares record
|
|
116 |
||
117 |
Copies data from original unpacked record into the preallocated chunkset,
|
|
118 |
or performs data comparison
|
|
119 |
||
120 |
@param info the hosting table
|
|
121 |
@param record the record in standard unpacked format
|
|
122 |
@param pos the target chunkset
|
|
123 |
@param is_compare flag indicating whether we should compare data or store it
|
|
124 |
||
125 |
@return Status of comparison
|
|
126 |
@retval non-zero if comparison fond data differences
|
|
127 |
@retval zero otherwise
|
|
128 |
*/
|
|
129 |
||
482
by Brian Aker
Remove uint. |
130 |
uint32_t hp_process_record_data_to_chunkset(HP_SHARE *info, const unsigned char *record, |
131 |
unsigned char *pos, uint32_t is_compare) |
|
244.1.1
by Harrison Fisk
Port Ebay/Google memory storage engine variable width columns. |
132 |
{
|
482
by Brian Aker
Remove uint. |
133 |
uint32_t i, dst_offset; |
481
by Brian Aker
Remove all of uchar. |
134 |
unsigned char* curr_chunk= pos; |
244.1.1
by Harrison Fisk
Port Ebay/Google memory storage engine variable width columns. |
135 |
|
136 |
if (is_compare) |
|
137 |
{
|
|
138 |
if (memcmp(curr_chunk, record, (size_t) info->fixed_data_length)) |
|
139 |
{
|
|
140 |
return 1; |
|
141 |
}
|
|
142 |
}
|
|
143 |
else
|
|
144 |
{
|
|
145 |
memcpy(curr_chunk, record, (size_t) info->fixed_data_length); |
|
146 |
}
|
|
147 |
||
148 |
if (!info->recordspace.is_variable_size) |
|
149 |
{
|
|
150 |
/* Nothing more to copy */
|
|
151 |
return 0; |
|
152 |
}
|
|
153 |
||
154 |
dst_offset= info->fixed_data_length; |
|
155 |
||
156 |
for (i= info->fixed_column_count; i < info->column_count; i++) |
|
157 |
{
|
|
482
by Brian Aker
Remove uint. |
158 |
uint32_t src_offset, length; |
244.1.1
by Harrison Fisk
Port Ebay/Google memory storage engine variable width columns. |
159 |
|
160 |
HP_COLUMNDEF* column= info->column_defs + i; |
|
161 |
||
162 |
if (column->null_bit) |
|
163 |
{
|
|
164 |
if (record[column->null_pos] & column->null_bit) |
|
165 |
{
|
|
166 |
/* Skip all NULL values */
|
|
167 |
continue; |
|
168 |
}
|
|
169 |
}
|
|
170 |
||
171 |
src_offset= column->offset; |
|
172 |
if (column->type == DRIZZLE_TYPE_VARCHAR) |
|
173 |
{
|
|
482
by Brian Aker
Remove uint. |
174 |
uint32_t pack_length; |
244.1.1
by Harrison Fisk
Port Ebay/Google memory storage engine variable width columns. |
175 |
|
176 |
/* >= 5.0.3 true VARCHAR */
|
|
177 |
||
178 |
/* Make sure to copy length indicator and actuals string bytes */
|
|
179 |
pack_length= column->length_bytes; |
|
180 |
length= pack_length + (pack_length == 1 ? |
|
481
by Brian Aker
Remove all of uchar. |
181 |
(uint) *(unsigned char*) (record + src_offset) : uint2korr(record + src_offset)); |
244.1.1
by Harrison Fisk
Port Ebay/Google memory storage engine variable width columns. |
182 |
}
|
183 |
else
|
|
184 |
{
|
|
185 |
length= column->length; |
|
186 |
}
|
|
187 |
||
188 |
while (length > 0) |
|
189 |
{
|
|
482
by Brian Aker
Remove uint. |
190 |
uint32_t to_copy; |
244.1.1
by Harrison Fisk
Port Ebay/Google memory storage engine variable width columns. |
191 |
|
192 |
to_copy= info->recordspace.chunk_dataspace_length - dst_offset; |
|
193 |
if (to_copy == 0) |
|
194 |
{
|
|
195 |
/* Jump to the next chunk */
|
|
196 |
/*dump_chunk(info, curr_chunk);*/
|
|
481
by Brian Aker
Remove all of uchar. |
197 |
curr_chunk= *((unsigned char**) (curr_chunk + info->recordspace.offset_link)); |
244.1.1
by Harrison Fisk
Port Ebay/Google memory storage engine variable width columns. |
198 |
dst_offset= 0; |
199 |
continue; |
|
200 |
}
|
|
201 |
||
1067.4.8
by Nathan Williams
Converted all usages of cmin/cmax in plugin directory to std::min/max. |
202 |
to_copy= min(length, to_copy); |
244.1.1
by Harrison Fisk
Port Ebay/Google memory storage engine variable width columns. |
203 |
|
204 |
if (is_compare) |
|
205 |
{
|
|
206 |
if (memcmp(curr_chunk + dst_offset, record + src_offset, (size_t) to_copy)) |
|
207 |
{
|
|
208 |
return 1; |
|
209 |
}
|
|
210 |
}
|
|
211 |
else
|
|
212 |
{
|
|
213 |
memcpy(curr_chunk + dst_offset, record + src_offset, (size_t) to_copy); |
|
214 |
}
|
|
215 |
||
216 |
src_offset+= to_copy; |
|
217 |
dst_offset+= to_copy; |
|
218 |
length-= to_copy; |
|
219 |
}
|
|
220 |
}
|
|
221 |
||
222 |
/*dump_chunk(info, curr_chunk);*/
|
|
223 |
return 0; |
|
224 |
}
|
|
225 |
||
226 |
||
227 |
/**
|
|
228 |
Stores record in the heap table chunks
|
|
229 |
||
230 |
Copies data from original unpacked record into the preallocated chunkset
|
|
231 |
||
232 |
@param info the hosting table
|
|
233 |
@param record the record in standard unpacked format
|
|
234 |
@param pos the target chunkset
|
|
235 |
*/
|
|
236 |
||
481
by Brian Aker
Remove all of uchar. |
237 |
void hp_copy_record_data_to_chunkset(HP_SHARE *info, const unsigned char *record, unsigned char *pos) |
244.1.1
by Harrison Fisk
Port Ebay/Google memory storage engine variable width columns. |
238 |
{
|
239 |
||
240 |
hp_process_record_data_to_chunkset(info, record, pos, 0); |
|
241 |
||
242 |
return; |
|
243 |
}
|
|
244 |
||
245 |
||
246 |
/*
|
|
247 |
Macro to switch curr_chunk to the next chunk in the chunkset and reset src_offset
|
|
248 |
*/
|
|
249 |
#define SWITCH_TO_NEXT_CHUNK_FOR_READ(info, curr_chunk, src_offset) \
|
|
250 |
{ \
|
|
481
by Brian Aker
Remove all of uchar. |
251 |
curr_chunk= *((unsigned char**) (curr_chunk + info->recordspace.offset_link)); \
|
244.1.1
by Harrison Fisk
Port Ebay/Google memory storage engine variable width columns. |
252 |
src_offset= 0; \
|
253 |
/*dump_chunk(info, curr_chunk);*/ \ |
|
254 |
}
|
|
255 |
||
256 |
||
257 |
/**
|
|
258 |
Copies record data from storage to unpacked record format
|
|
259 |
||
260 |
Copies data from chunkset into its original unpacked record
|
|
261 |
||
262 |
@param info the hosting table
|
|
263 |
@param[out] record the target record in standard unpacked format
|
|
264 |
@param pos the source chunkset
|
|
265 |
*/
|
|
266 |
||
481
by Brian Aker
Remove all of uchar. |
267 |
void hp_extract_record(HP_SHARE *info, unsigned char *record, const unsigned char *pos) |
244.1.1
by Harrison Fisk
Port Ebay/Google memory storage engine variable width columns. |
268 |
{
|
482
by Brian Aker
Remove uint. |
269 |
uint32_t i, src_offset; |
481
by Brian Aker
Remove all of uchar. |
270 |
const unsigned char* curr_chunk= pos; |
244.1.1
by Harrison Fisk
Port Ebay/Google memory storage engine variable width columns. |
271 |
|
272 |
||
273 |
/*if (info->is_variable_size)
|
|
274 |
{
|
|
275 |
dump_chunk(info, curr_chunk);
|
|
276 |
}*/
|
|
277 |
||
278 |
memcpy(record, curr_chunk, (size_t) info->fixed_data_length); |
|
279 |
||
280 |
if (!info->recordspace.is_variable_size) |
|
281 |
{
|
|
282 |
/* Nothing more to copy */
|
|
283 |
return; |
|
284 |
}
|
|
285 |
||
286 |
src_offset= info->fixed_data_length; |
|
287 |
||
288 |
for (i= info->fixed_column_count; i < info->column_count; i++) |
|
289 |
{
|
|
482
by Brian Aker
Remove uint. |
290 |
uint32_t dst_offset, length, is_null = 0; |
244.1.1
by Harrison Fisk
Port Ebay/Google memory storage engine variable width columns. |
291 |
|
292 |
HP_COLUMNDEF* column= info->column_defs + i; |
|
293 |
||
294 |
if (column->null_bit) |
|
295 |
{
|
|
296 |
if (record[column->null_pos] & column->null_bit) |
|
297 |
{
|
|
298 |
is_null = 1; |
|
299 |
}
|
|
300 |
}
|
|
301 |
||
302 |
dst_offset= column->offset; |
|
303 |
if (column->type == DRIZZLE_TYPE_VARCHAR) |
|
304 |
{
|
|
482
by Brian Aker
Remove uint. |
305 |
uint32_t pack_length, byte1, byte2; |
244.1.1
by Harrison Fisk
Port Ebay/Google memory storage engine variable width columns. |
306 |
|
307 |
/* >= 5.0.3 true VARCHAR */
|
|
308 |
||
309 |
if (is_null) |
|
310 |
{
|
|
311 |
/* TODO: is memset really needed? */
|
|
312 |
memset(record + column->offset, 0, column->length); |
|
313 |
continue; |
|
314 |
}
|
|
315 |
||
316 |
pack_length= column->length_bytes; |
|
317 |
||
318 |
if (src_offset == info->recordspace.chunk_dataspace_length) |
|
319 |
{
|
|
320 |
SWITCH_TO_NEXT_CHUNK_FOR_READ(info, curr_chunk, src_offset); |
|
321 |
}
|
|
481
by Brian Aker
Remove all of uchar. |
322 |
byte1= *(unsigned char*) (curr_chunk + src_offset++); |
244.1.1
by Harrison Fisk
Port Ebay/Google memory storage engine variable width columns. |
323 |
*(record + dst_offset++)= byte1; |
324 |
||
325 |
if (pack_length == 1) |
|
326 |
{
|
|
327 |
length= byte1; |
|
328 |
}
|
|
329 |
else
|
|
330 |
{
|
|
331 |
if (src_offset == info->recordspace.chunk_dataspace_length) |
|
332 |
{
|
|
333 |
SWITCH_TO_NEXT_CHUNK_FOR_READ(info, curr_chunk, src_offset); |
|
334 |
}
|
|
481
by Brian Aker
Remove all of uchar. |
335 |
byte2= *(unsigned char*) (curr_chunk + src_offset++); |
244.1.1
by Harrison Fisk
Port Ebay/Google memory storage engine variable width columns. |
336 |
*(record + dst_offset++)= byte2; |
337 |
||
338 |
/* We copy byte-by-byte and then use uint2korr to combine bytes in the right order */
|
|
339 |
length= uint2korr(record + dst_offset - 2); |
|
340 |
}
|
|
341 |
}
|
|
342 |
else
|
|
343 |
{
|
|
344 |
if (is_null) |
|
345 |
{
|
|
346 |
/* TODO: is memset really needed? */
|
|
347 |
memset(record + column->offset, 0, column->length); |
|
348 |
continue; |
|
349 |
}
|
|
350 |
||
351 |
length= column->length; |
|
352 |
}
|
|
353 |
||
354 |
while (length > 0) |
|
355 |
{
|
|
482
by Brian Aker
Remove uint. |
356 |
uint32_t to_copy; |
244.1.1
by Harrison Fisk
Port Ebay/Google memory storage engine variable width columns. |
357 |
|
358 |
to_copy= info->recordspace.chunk_dataspace_length - src_offset; |
|
359 |
if (to_copy == 0) |
|
360 |
{
|
|
361 |
SWITCH_TO_NEXT_CHUNK_FOR_READ(info, curr_chunk, src_offset); |
|
362 |
to_copy= info->recordspace.chunk_dataspace_length; |
|
363 |
}
|
|
364 |
||
1067.4.8
by Nathan Williams
Converted all usages of cmin/cmax in plugin directory to std::min/max. |
365 |
to_copy= min(length, to_copy); |
244.1.1
by Harrison Fisk
Port Ebay/Google memory storage engine variable width columns. |
366 |
|
367 |
memcpy(record + dst_offset, curr_chunk + src_offset, (size_t) to_copy); |
|
368 |
src_offset+= to_copy; |
|
369 |
dst_offset+= to_copy; |
|
370 |
length-= to_copy; |
|
371 |
}
|
|
372 |
}
|
|
373 |
||
374 |
return; |
|
375 |
}
|