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