~drizzle-trunk/drizzle/development

1 by brian
clean slate
1
/* Copyright (C) 2000-2006 MySQL AB
2
3
   This program is free software; you can redistribute it and/or modify
4
   it under the terms of the GNU General Public License as published by
5
   the Free Software Foundation; version 2 of the License.
6
7
   This program is distributed in the hope that it will be useful,
8
   but WITHOUT ANY WARRANTY; without even the implied warranty of
9
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
   GNU General Public License for more details.
11
12
   You should have received a copy of the GNU General Public License
13
   along with this program; if not, write to the Free Software
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
16
/**
17
  @file
18
19
  @brief
20
  Functions for easy reading of records, possible through a cache
21
*/
243.1.17 by Jay Pipes
FINAL PHASE removal of mysql_priv.h (Bye, bye my friend.)
22
#include <drizzled/server_includes.h>
550 by Monty Taylor
Moved error.h into just the files that need it.
23
#include <drizzled/error.h>
584.1.15 by Monty Taylor
The mega-patch from hell. Renamed sql_class to session (since that's what it is) and removed it and field and table from common_includes.
24
#include <drizzled/table.h>
25
#include <drizzled/session.h>
1 by brian
clean slate
26
1039.2.8 by Jay Pipes
Yet more indentation and style cleanup
27
int rr_sequential(READ_RECORD *info);
1 by brian
clean slate
28
static int rr_quick(READ_RECORD *info);
29
static int rr_from_tempfile(READ_RECORD *info);
30
static int rr_unpack_from_tempfile(READ_RECORD *info);
31
static int rr_unpack_from_buffer(READ_RECORD *info);
32
static int rr_from_pointers(READ_RECORD *info);
33
static int rr_from_cache(READ_RECORD *info);
520.1.22 by Brian Aker
Second pass of thd cleanup
34
static int init_rr_cache(Session *session, READ_RECORD *info);
481 by Brian Aker
Remove all of uchar.
35
static int rr_cmp(unsigned char *a,unsigned char *b);
1 by brian
clean slate
36
static int rr_index_first(READ_RECORD *info);
37
static int rr_index(READ_RECORD *info);
38
39
/**
40
  Initialize READ_RECORD structure to perform full index scan (in forward
41
  direction) using read_record.read_record() interface.
42
43
    This function has been added at late stage and is used only by
44
    UPDATE/DELETE. Other statements perform index scans using
45
    join_read_first/next functions.
46
47
  @param info         READ_RECORD structure to initialize.
520.1.22 by Brian Aker
Second pass of thd cleanup
48
  @param session          Thread handle
1 by brian
clean slate
49
  @param table        Table to be accessed
50
  @param print_error  If true, call table->file->print_error() if an error
51
                      occurs (except for end-of-records error)
52
  @param idx          index to scan
53
*/
1039.2.8 by Jay Pipes
Yet more indentation and style cleanup
54
void init_read_record_idx(READ_RECORD *info, 
55
                          Session *, 
56
                          Table *table,
57
                          bool print_error, 
58
                          uint32_t idx)
1 by brian
clean slate
59
{
997.5.1 by chris
Replace macros around unireg.h, store_record,restore_record,cmp_record,empty_record
60
  table->emptyRecord();
212.6.6 by Mats Kindahl
Removing redundant use of casts in drizzled/ for memcmp(), memcpy(), memset(), and memmove().
61
  memset(info, 0, sizeof(*info));
1 by brian
clean slate
62
  info->table= table;
63
  info->file=  table->file;
64
  info->record= table->record[0];
65
  info->print_error= print_error;
66
67
  table->status=0;			/* And it's always found */
68
  if (!table->file->inited)
69
    table->file->ha_index_init(idx, 1);
70
  /* read_record will be changed to rr_index in rr_index_first */
71
  info->read_record= rr_index_first;
72
}
73
74
/*
75
  init_read_record is used to scan by using a number of different methods.
76
  Which method to use is set-up in this call so that later calls to
77
  the info->read_record will call the appropriate method using a function
78
  pointer.
79
80
  There are five methods that relate completely to the sort function
81
  filesort. The result of a filesort is retrieved using read_record
82
  calls. The other two methods are used for normal table access.
83
84
  The filesort will produce references to the records sorted, these
85
  references can be stored in memory or in a temporary file.
86
87
  The temporary file is normally used when the references doesn't fit into
88
  a properly sized memory buffer. For most small queries the references
89
  are stored in the memory buffer.
90
91
  The temporary file is also used when performing an update where a key is
92
  modified.
93
94
  Methods used when ref's are in memory (using rr_from_pointers):
95
    rr_unpack_from_buffer:
96
    ----------------------
97
      This method is used when table->sort.addon_field is allocated.
98
      This is allocated for most SELECT queries not involving any BLOB's.
99
      In this case the records are fetched from a memory buffer.
100
    rr_from_pointers:
101
    -----------------
102
      Used when the above is not true, UPDATE, DELETE and so forth and
103
      SELECT's involving BLOB's. It is also used when the addon_field
104
      buffer is not allocated due to that its size was bigger than the
105
      session variable max_length_for_sort_data.
106
      In this case the record data is fetched from the handler using the
107
      saved reference using the rnd_pos handler call.
108
109
  Methods used when ref's are in a temporary file (using rr_from_tempfile)
110
    rr_unpack_from_tempfile:
111
    ------------------------
112
      Same as rr_unpack_from_buffer except that references are fetched from
113
      temporary file. Should obviously not really happen other than in
114
      strange configurations.
115
116
    rr_from_tempfile:
117
    -----------------
118
      Same as rr_from_pointers except that references are fetched from
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
119
      temporary file instead of from
1 by brian
clean slate
120
    rr_from_cache:
121
    --------------
122
      This is a special variant of rr_from_tempfile that can be used for
123
      handlers that is not using the HA_FAST_KEY_READ table flag. Instead
124
      of reading the references one by one from the temporary file it reads
125
      a set of them, sorts them and reads all of them into a buffer which
126
      is then used for a number of subsequent calls to rr_from_cache.
127
      It is only used for SELECT queries and a number of other conditions
128
      on table size.
129
130
  All other accesses use either index access methods (rr_quick) or a full
131
  table scan (rr_sequential).
132
  rr_quick:
133
  ---------
134
    rr_quick uses one of the QUICK_SELECT classes in opt_range.cc to
135
    perform an index scan. There are loads of functionality hidden
136
    in these quick classes. It handles all index scans of various kinds.
137
  rr_sequential:
138
  --------------
139
    This is the most basic access method of a table using rnd_init,
140
    rnd_next and rnd_end. No indexes are used.
141
*/
1039.2.8 by Jay Pipes
Yet more indentation and style cleanup
142
void init_read_record(READ_RECORD *info,
143
                      Session *session, 
144
                      Table *table,
145
		                  SQL_SELECT *select,
146
		                  int use_record_cache, 
147
                      bool print_error)
1 by brian
clean slate
148
{
149
  IO_CACHE *tempfile;
150
212.6.6 by Mats Kindahl
Removing redundant use of casts in drizzled/ for memcmp(), memcpy(), memset(), and memmove().
151
  memset(info, 0, sizeof(*info));
520.1.22 by Brian Aker
Second pass of thd cleanup
152
  info->session=session;
1 by brian
clean slate
153
  info->table=table;
154
  info->file= table->file;
155
  info->forms= &info->table;		/* Only one table */
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
156
1 by brian
clean slate
157
  if (table->s->tmp_table == NON_TRANSACTIONAL_TMP_TABLE &&
158
      !table->sort.addon_field)
398.1.10 by Monty Taylor
Actually removed VOID() this time.
159
    table->file->extra(HA_EXTRA_MMAP);
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
160
1 by brian
clean slate
161
  if (table->sort.addon_field)
162
  {
163
    info->rec_buf= table->sort.addon_buf;
164
    info->ref_length= table->sort.addon_length;
165
  }
166
  else
167
  {
997.5.1 by chris
Replace macros around unireg.h, store_record,restore_record,cmp_record,empty_record
168
    table->emptyRecord();
1 by brian
clean slate
169
    info->record= table->record[0];
170
    info->ref_length= table->file->ref_length;
171
  }
172
  info->select=select;
173
  info->print_error=print_error;
174
  info->ignore_not_found_rows= 0;
175
  table->status=0;			/* And it's always found */
176
177
  if (select && my_b_inited(&select->file))
178
    tempfile= &select->file;
179
  else
180
    tempfile= table->sort.io_cache;
181
  if (tempfile && my_b_inited(tempfile)) // Test if ref-records was used
182
  {
183
    info->read_record= (table->sort.addon_field ?
184
                        rr_unpack_from_tempfile : rr_from_tempfile);
185
    info->io_cache=tempfile;
186
    reinit_io_cache(info->io_cache,READ_CACHE,0L,0,0);
187
    info->ref_pos=table->file->ref;
188
    if (!table->file->inited)
189
      table->file->ha_rnd_init(0);
190
191
    /*
192
      table->sort.addon_field is checked because if we use addon fields,
193
      it doesn't make sense to use cache - we don't read from the table
194
      and table->sort.io_cache is read sequentially
195
    */
196
    if (!table->sort.addon_field &&
1039.2.8 by Jay Pipes
Yet more indentation and style cleanup
197
        session->variables.read_rnd_buff_size &&
198
        !(table->file->ha_table_flags() & HA_FAST_KEY_READ) &&
199
        (table->db_stat & HA_READ_ONLY ||
200
        table->reginfo.lock_type <= TL_READ_NO_INSERT) &&
201
        (uint64_t) table->s->reclength* (table->file->stats.records+
202
                                                table->file->stats.deleted) >
203
        (uint64_t) MIN_FILE_LENGTH_TO_USE_ROW_CACHE &&
204
        info->io_cache->end_of_file/info->ref_length * table->s->reclength >
205
        (my_off_t) MIN_ROWS_TO_USE_TABLE_CACHE &&
206
        !table->s->blob_fields &&
1 by brian
clean slate
207
        info->ref_length <= MAX_REFLENGTH)
208
    {
520.1.22 by Brian Aker
Second pass of thd cleanup
209
      if (! init_rr_cache(session, info))
1 by brian
clean slate
210
      {
1039.2.8 by Jay Pipes
Yet more indentation and style cleanup
211
        info->read_record=rr_from_cache;
1 by brian
clean slate
212
      }
213
    }
214
  }
215
  else if (select && select->quick)
216
  {
217
    info->read_record=rr_quick;
218
  }
219
  else if (table->sort.record_pointers)
220
  {
221
    table->file->ha_rnd_init(0);
222
    info->cache_pos=table->sort.record_pointers;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
223
    info->cache_end=info->cache_pos+
1 by brian
clean slate
224
                    table->sort.found_records*info->ref_length;
225
    info->read_record= (table->sort.addon_field ?
226
                        rr_unpack_from_buffer : rr_from_pointers);
227
  }
228
  else
229
  {
230
    info->read_record=rr_sequential;
231
    table->file->ha_rnd_init(1);
232
    /* We can use record cache if we don't update dynamic length tables */
233
    if (!table->no_cache &&
1039.2.8 by Jay Pipes
Yet more indentation and style cleanup
234
        (use_record_cache > 0 ||
235
        (int) table->reginfo.lock_type <= (int) TL_READ_WITH_SHARED_LOCKS ||
236
        !(table->s->db_options_in_use & HA_OPTION_PACK_RECORD) ||
237
        (use_record_cache < 0 &&
238
          !(table->file->ha_table_flags() & HA_NOT_DELETE_WITH_CACHE))))
520.1.22 by Brian Aker
Second pass of thd cleanup
239
      table->file->extra_opt(HA_EXTRA_CACHE, session->variables.read_buff_size);
1 by brian
clean slate
240
  }
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
241
  /*
1 by brian
clean slate
242
    Do condition pushdown for UPDATE/DELETE.
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
243
    TODO: Remove this from here as it causes two condition pushdown calls
1 by brian
clean slate
244
    when we're running a SELECT and the condition cannot be pushed down.
245
  */
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
246
  if (session->variables.engine_condition_pushdown &&
247
      select && select->cond &&
1 by brian
clean slate
248
      (select->cond->used_tables() & table->map) &&
249
      !table->file->pushed_cond)
250
    table->file->cond_push(select->cond);
251
51.1.4 by Jay Pipes
Removed all DBUG_XXX content from records.cc. Builds/tests run fine. On to next file...
252
  return;
1 by brian
clean slate
253
} /* init_read_record */
254
255
void end_read_record(READ_RECORD *info)
256
{                   /* free cache if used */
257
  if (info->cache)
258
  {
477 by Monty Taylor
Removed my_free(). It turns out that it had been def'd to ignore the flags passed to it in the second arg anyway. Gotta love that.
259
    free((char*) info->cache);
1 by brian
clean slate
260
    info->cache=0;
261
  }
262
  if (info->table)
263
  {
264
    filesort_free_buffers(info->table,0);
265
    (void) info->file->extra(HA_EXTRA_NO_CACHE);
266
    if (info->read_record != rr_quick) // otherwise quick_range does it
267
      (void) info->file->ha_index_or_rnd_end();
268
    info->table=0;
269
  }
270
}
271
272
static int rr_handle_error(READ_RECORD *info, int error)
273
{
274
  if (error == HA_ERR_END_OF_FILE)
275
    error= -1;
276
  else
277
  {
278
    if (info->print_error)
279
      info->table->file->print_error(error, MYF(0));
280
    if (error < 0)                            // Fix negative BDB errno
281
      error= 1;
282
  }
283
  return error;
284
}
285
286
/** Read a record from head-database. */
287
static int rr_quick(READ_RECORD *info)
288
{
289
  int tmp;
290
  while ((tmp= info->select->quick->get_next()))
291
  {
520.1.22 by Brian Aker
Second pass of thd cleanup
292
    if (info->session->killed)
1 by brian
clean slate
293
    {
294
      my_error(ER_SERVER_SHUTDOWN, MYF(0));
295
      return 1;
296
    }
297
    if (tmp != HA_ERR_RECORD_DELETED)
298
    {
299
      tmp= rr_handle_error(info, tmp);
300
      break;
301
    }
302
  }
998.1.2 by Brian Aker
First pass on removing virt columns
303
1 by brian
clean slate
304
  return tmp;
305
}
306
307
/**
308
  Reads first row in an index scan.
309
310
  @param info  	Scan info
311
312
  @retval
313
    0   Ok
314
  @retval
315
    -1   End of records
316
  @retval
317
    1   Error
318
*/
319
static int rr_index_first(READ_RECORD *info)
320
{
321
  int tmp= info->file->index_first(info->record);
322
  info->read_record= rr_index;
323
  if (tmp)
324
    tmp= rr_handle_error(info, tmp);
325
  return tmp;
326
}
327
328
/**
329
  Reads index sequentially after first row.
330
331
  Read the next index record (in forward direction) and translate return
332
  value.
333
334
  @param info  Scan info
335
336
  @retval
337
    0   Ok
338
  @retval
339
    -1   End of records
340
  @retval
341
    1   Error
342
*/
343
static int rr_index(READ_RECORD *info)
344
{
345
  int tmp= info->file->index_next(info->record);
346
  if (tmp)
347
    tmp= rr_handle_error(info, tmp);
348
  return tmp;
349
}
350
351
int rr_sequential(READ_RECORD *info)
352
{
353
  int tmp;
822 by Brian Aker
Merge from Stewart.
354
  while ((tmp= info->file->rnd_next(info->record)))
1 by brian
clean slate
355
  {
520.1.22 by Brian Aker
Second pass of thd cleanup
356
    if (info->session->killed)
1 by brian
clean slate
357
    {
520.1.22 by Brian Aker
Second pass of thd cleanup
358
      info->session->send_kill_message();
1 by brian
clean slate
359
      return 1;
360
    }
361
    /*
822 by Brian Aker
Merge from Stewart.
362
      TODO> Fix this so that engine knows how to behave on its own.
1 by brian
clean slate
363
      rnd_next can return RECORD_DELETED for MyISAM when one thread is
364
      reading and another deleting without locks.
365
    */
366
    if (tmp != HA_ERR_RECORD_DELETED)
367
    {
368
      tmp= rr_handle_error(info, tmp);
369
      break;
370
    }
371
  }
998.1.2 by Brian Aker
First pass on removing virt columns
372
1 by brian
clean slate
373
  return tmp;
374
}
375
376
static int rr_from_tempfile(READ_RECORD *info)
377
{
378
  int tmp;
379
  for (;;)
380
  {
381
    if (my_b_read(info->io_cache,info->ref_pos,info->ref_length))
382
      return -1;					/* End of file */
383
    if (!(tmp=info->file->rnd_pos(info->record,info->ref_pos)))
384
      break;
385
    /* The following is extremely unlikely to happen */
386
    if (tmp == HA_ERR_RECORD_DELETED ||
387
        (tmp == HA_ERR_KEY_NOT_FOUND && info->ignore_not_found_rows))
388
      continue;
389
    tmp= rr_handle_error(info, tmp);
390
    break;
391
  }
392
  return tmp;
393
} /* rr_from_tempfile */
394
395
/**
396
  Read a result set record from a temporary file after sorting.
397
398
  The function first reads the next sorted record from the temporary file.
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
399
  into a buffer. If a success it calls a callback function that unpacks
1 by brian
clean slate
400
  the fields values use in the result set from this buffer into their
401
  positions in the regular record buffer.
402
403
  @param info          Reference to the context including record descriptors
404
405
  @retval
406
    0   Record successfully read.
407
  @retval
408
    -1   There is no record to be read anymore.
409
*/
410
static int rr_unpack_from_tempfile(READ_RECORD *info)
411
{
412
  if (my_b_read(info->io_cache, info->rec_buf, info->ref_length))
413
    return -1;
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
414
  Table *table= info->table;
1 by brian
clean slate
415
  (*table->sort.unpack)(table->sort.addon_field, info->rec_buf);
416
417
  return 0;
418
}
419
420
static int rr_from_pointers(READ_RECORD *info)
421
{
422
  int tmp;
481 by Brian Aker
Remove all of uchar.
423
  unsigned char *cache_pos;
1 by brian
clean slate
424
425
  for (;;)
426
  {
427
    if (info->cache_pos == info->cache_end)
428
      return -1;					/* End of file */
429
    cache_pos= info->cache_pos;
430
    info->cache_pos+= info->ref_length;
431
432
    if (!(tmp=info->file->rnd_pos(info->record,cache_pos)))
433
      break;
434
435
    /* The following is extremely unlikely to happen */
436
    if (tmp == HA_ERR_RECORD_DELETED ||
437
        (tmp == HA_ERR_KEY_NOT_FOUND && info->ignore_not_found_rows))
438
      continue;
439
    tmp= rr_handle_error(info, tmp);
440
    break;
441
  }
442
  return tmp;
443
}
444
445
/**
446
  Read a result set record from a buffer after sorting.
447
448
  The function first reads the next sorted record from the sort buffer.
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
449
  If a success it calls a callback function that unpacks
1 by brian
clean slate
450
  the fields values use in the result set from this buffer into their
451
  positions in the regular record buffer.
452
453
  @param info          Reference to the context including record descriptors
454
455
  @retval
456
    0   Record successfully read.
457
  @retval
458
    -1   There is no record to be read anymore.
459
*/
460
static int rr_unpack_from_buffer(READ_RECORD *info)
461
{
462
  if (info->cache_pos == info->cache_end)
463
    return -1;                      /* End of buffer */
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
464
  Table *table= info->table;
1 by brian
clean slate
465
  (*table->sort.unpack)(table->sort.addon_field, info->cache_pos);
466
  info->cache_pos+= info->ref_length;
467
468
  return 0;
469
}
470
1039.2.8 by Jay Pipes
Yet more indentation and style cleanup
471
/* cacheing of records from a database */
520.1.22 by Brian Aker
Second pass of thd cleanup
472
static int init_rr_cache(Session *session, READ_RECORD *info)
1 by brian
clean slate
473
{
482 by Brian Aker
Remove uint.
474
  uint32_t rec_cache_size;
1 by brian
clean slate
475
476
  info->struct_length= 3+MAX_REFLENGTH;
477
  info->reclength= ALIGN_SIZE(info->table->s->reclength+1);
478
  if (info->reclength < info->struct_length)
479
    info->reclength= ALIGN_SIZE(info->struct_length);
480
481
  info->error_offset= info->table->s->reclength;
520.1.22 by Brian Aker
Second pass of thd cleanup
482
  info->cache_records= (session->variables.read_rnd_buff_size /
1 by brian
clean slate
483
                        (info->reclength+info->struct_length));
484
  rec_cache_size= info->cache_records*info->reclength;
485
  info->rec_cache_size= info->cache_records*info->ref_length;
486
487
  // We have to allocate one more byte to use uint3korr (see comments for it)
488
  if (info->cache_records <= 2 ||
641.3.7 by Monty Taylor
More my_malloc removal.
489
      !(info->cache=(unsigned char*) malloc(rec_cache_size+info->cache_records*
490
					    info->struct_length+1)))
51.1.4 by Jay Pipes
Removed all DBUG_XXX content from records.cc. Builds/tests run fine. On to next file...
491
    return(1);
1 by brian
clean slate
492
#ifdef HAVE_purify
493
  // Avoid warnings in qsort
212.6.1 by Mats Kindahl
Replacing all bzero() calls with memset() calls and removing the bzero.c file.
494
  memset(info->cache, 0,
495
         rec_cache_size+info->cache_records* info->struct_length+1);
1 by brian
clean slate
496
#endif
497
  info->read_positions=info->cache+rec_cache_size;
498
  info->cache_pos=info->cache_end=info->cache;
51.1.4 by Jay Pipes
Removed all DBUG_XXX content from records.cc. Builds/tests run fine. On to next file...
499
  return(0);
1 by brian
clean slate
500
} /* init_rr_cache */
501
502
static int rr_from_cache(READ_RECORD *info)
503
{
482 by Brian Aker
Remove uint.
504
  register uint32_t i;
308 by Brian Aker
ulong conversion
505
  uint32_t length;
1 by brian
clean slate
506
  my_off_t rest_of_file;
206 by Brian Aker
Removed final uint dead types.
507
  int16_t error;
481 by Brian Aker
Remove all of uchar.
508
  unsigned char *position,*ref_position,*record_pos;
308 by Brian Aker
ulong conversion
509
  uint32_t record;
1 by brian
clean slate
510
511
  for (;;)
512
  {
513
    if (info->cache_pos != info->cache_end)
514
    {
515
      if (info->cache_pos[info->error_offset])
516
      {
1039.2.8 by Jay Pipes
Yet more indentation and style cleanup
517
        shortget(error,info->cache_pos);
518
        if (info->print_error)
519
          info->table->file->print_error(error,MYF(0));
1 by brian
clean slate
520
      }
521
      else
522
      {
1039.2.8 by Jay Pipes
Yet more indentation and style cleanup
523
        error=0;
524
        memcpy(info->record,info->cache_pos, (size_t) info->table->s->reclength);
1 by brian
clean slate
525
      }
526
      info->cache_pos+=info->reclength;
527
      return ((int) error);
528
    }
529
    length=info->rec_cache_size;
530
    rest_of_file=info->io_cache->end_of_file - my_b_tell(info->io_cache);
531
    if ((my_off_t) length > rest_of_file)
308 by Brian Aker
ulong conversion
532
      length= (uint32_t) rest_of_file;
1 by brian
clean slate
533
    if (!length || my_b_read(info->io_cache,info->cache,length))
534
    {
535
      return -1;			/* End of file */
536
    }
537
538
    length/=info->ref_length;
539
    position=info->cache;
540
    ref_position=info->read_positions;
541
    for (i=0 ; i < length ; i++,position+=info->ref_length)
542
    {
543
      memcpy(ref_position,position,(size_t) info->ref_length);
544
      ref_position+=MAX_REFLENGTH;
545
      int3store(ref_position,(long) i);
546
      ref_position+=3;
547
    }
548
    my_qsort(info->read_positions, length, info->struct_length,
549
             (qsort_cmp) rr_cmp);
550
551
    position=info->read_positions;
552
    for (i=0 ; i < length ; i++)
553
    {
554
      memcpy(info->ref_pos,position,(size_t) info->ref_length);
555
      position+=MAX_REFLENGTH;
556
      record=uint3korr(position);
557
      position+=3;
558
      record_pos=info->cache+record*info->reclength;
206 by Brian Aker
Removed final uint dead types.
559
      if ((error=(int16_t) info->file->rnd_pos(record_pos,info->ref_pos)))
1 by brian
clean slate
560
      {
1039.2.8 by Jay Pipes
Yet more indentation and style cleanup
561
        record_pos[info->error_offset]=1;
562
        shortstore(record_pos,error);
1 by brian
clean slate
563
      }
564
      else
1039.2.8 by Jay Pipes
Yet more indentation and style cleanup
565
        record_pos[info->error_offset]=0;
1 by brian
clean slate
566
    }
567
    info->cache_end=(info->cache_pos=info->cache)+length*info->reclength;
568
  }
569
} /* rr_from_cache */
570
481 by Brian Aker
Remove all of uchar.
571
static int rr_cmp(unsigned char *a,unsigned char *b)
1 by brian
clean slate
572
{
573
  if (a[0] != b[0])
574
    return (int) a[0] - (int) b[0];
575
  if (a[1] != b[1])
576
    return (int) a[1] - (int) b[1];
577
  if (a[2] != b[2])
578
    return (int) a[2] - (int) b[2];
579
#if MAX_REFLENGTH == 4
580
  return (int) a[3] - (int) b[3];
581
#else
582
  if (a[3] != b[3])
583
    return (int) a[3] - (int) b[3];
584
  if (a[4] != b[4])
585
    return (int) a[4] - (int) b[4];
586
  if (a[5] != b[5])
587
    return (int) a[1] - (int) b[5];
588
  if (a[6] != b[6])
589
    return (int) a[6] - (int) b[6];
590
  return (int) a[7] - (int) b[7];
591
#endif
592
}