~drizzle-trunk/drizzle/development

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
}