2001-05-23 15:26:42 +02:00
|
|
|
/*
|
|
|
|
* PROGRAM: JRD Sort
|
|
|
|
* MODULE: sort.h
|
|
|
|
* DESCRIPTION: Sort package definitions
|
|
|
|
*
|
|
|
|
* The contents of this file are subject to the Interbase Public
|
|
|
|
* License Version 1.0 (the "License"); you may not use this file
|
|
|
|
* except in compliance with the License. You may obtain a copy
|
|
|
|
* of the License at http://www.Inprise.com/IPL.html
|
|
|
|
*
|
|
|
|
* Software distributed under the License is distributed on an
|
|
|
|
* "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express
|
|
|
|
* or implied. See the License for the specific language governing
|
|
|
|
* rights and limitations under the License.
|
|
|
|
*
|
|
|
|
* The Original Code was created by Inprise Corporation
|
|
|
|
* and its predecessors. Portions created by Inprise Corporation are
|
|
|
|
* Copyright (C) Inprise Corporation.
|
|
|
|
*
|
|
|
|
* All Rights Reserved.
|
|
|
|
* Contributor(s): ______________________________________.
|
|
|
|
*/
|
|
|
|
|
2003-10-03 03:53:34 +02:00
|
|
|
#ifndef JRD_SORT_H
|
|
|
|
#define JRD_SORT_H
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
#include "../jrd/common.h"
|
|
|
|
#include "../jrd/fil.h"
|
|
|
|
|
2001-12-24 03:51:06 +01:00
|
|
|
#include "../jrd/jrd_blks.h"
|
|
|
|
#include "../include/fb_blk.h"
|
|
|
|
|
2004-03-20 15:57:40 +01:00
|
|
|
namespace Jrd {
|
|
|
|
|
2002-11-17 16:51:25 +01:00
|
|
|
// Forward declaration
|
2004-03-19 07:14:53 +01:00
|
|
|
struct sort_work_file;
|
2004-03-20 15:57:40 +01:00
|
|
|
class SortMem;
|
2004-03-28 11:10:30 +02:00
|
|
|
class Attachment;
|
|
|
|
struct irsb_sort;
|
|
|
|
struct merge_control;
|
2001-12-24 03:51:06 +01:00
|
|
|
|
2001-05-23 15:26:42 +02:00
|
|
|
/* SORTP is used throughout sort.c as a pointer into arrays of
|
|
|
|
longwords(32 bits). For 16 bit Windows, this must be a huge pointer.
|
|
|
|
|
|
|
|
Use this definition whenever doing pointer arithmetic, as
|
|
|
|
interbase variables (eg. scb->scb_longs) are in 32 - bit longwords. */
|
|
|
|
|
|
|
|
typedef ULONG SORTP;
|
|
|
|
|
|
|
|
/* since the first part of the record contains a back_pointer, whose
|
|
|
|
size depends on the platform (ie 16, 32 or 64 bits.).
|
2004-03-28 11:10:30 +02:00
|
|
|
This pointer data_type is defined by platform specific sort_ptr_t.
|
2001-05-23 15:26:42 +02:00
|
|
|
*/
|
|
|
|
|
2004-03-28 11:10:30 +02:00
|
|
|
typedef IPTR sort_ptr_t;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
/* # of 32 bit longs in a pointer (ie 1 on 32 bit machines 2 on 64 bit)*/
|
|
|
|
#define LONGS_PER_POINTER (sizeof (SLONG*) / sizeof (SLONG))
|
|
|
|
/* the size of sr_bckptr in # of 32 bit longwords */
|
|
|
|
#define SIZEOF_SR_BCKPTR_IN_LONGS LONGS_PER_POINTER
|
|
|
|
|
|
|
|
#define PREV_RUN_RECORD(record) (((SORTP *) record - scb->scb_longs))
|
|
|
|
#define NEXT_RUN_RECORD(record) (((SORTP *) record + scb->scb_longs))
|
|
|
|
|
|
|
|
/* a macro to goto the key_id part of a particular record.
|
|
|
|
Pls. refer to the SR structure in sort.h for an explanation of
|
|
|
|
the record structure . */
|
|
|
|
#define KEYOF(record) ((SORTP *)(((SR*)record)->sr_sort_record.sort_record_key))
|
|
|
|
|
|
|
|
/* macro to point to the next/previous record for sorting.
|
|
|
|
still using scb_longs as we cannot do record++ */
|
|
|
|
#define PREV_RECORD(record) ((SR*)((SORTP *) record + scb->scb_longs))
|
|
|
|
#define NEXT_RECORD(record) ((SR*)((SORTP *) record - scb->scb_longs))
|
|
|
|
|
|
|
|
/* structure containing the key and data part of the sort record,
|
|
|
|
the back pointer is not written to the disk, this is how the records
|
|
|
|
look in the run files. */
|
|
|
|
|
2004-03-19 07:14:53 +01:00
|
|
|
struct sort_record
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
ULONG sort_record_key[1];
|
|
|
|
/* Sorting key. Mangled by diddle_key to
|
|
|
|
compare using ULONG word compares (size
|
|
|
|
is rounded upwards if necessary).
|
|
|
|
Min length of 1 ULONG, max indeterminate
|
|
|
|
For current sort, length is stored as
|
|
|
|
scb_key_length.
|
|
|
|
Keys are created by BTR_* routines as
|
|
|
|
sequences of ULONG - this representation
|
|
|
|
cannot be easily changed. */
|
|
|
|
|
|
|
|
/* sort_record_data is here to explain the sort record.
|
|
|
|
To get to the data part of a record add scb->scb_key_length to a pointer
|
|
|
|
pointing to the start of the sort_record_key.
|
|
|
|
|
|
|
|
ULONG sort_record_data [1];
|
|
|
|
Data values, not part of key,
|
|
|
|
that are pumped through sort.
|
|
|
|
Min length of 0, max indeterminate,
|
|
|
|
byte data, but starts on ULONG boundary and
|
|
|
|
rounded up to ULONG size
|
|
|
|
Sizeof sr_data array would be
|
|
|
|
(scb_longs - scb_key_length)*sizeof(ULONG) -
|
|
|
|
sizeof(sr_bckptr)
|
|
|
|
*/
|
|
|
|
|
2004-03-19 07:14:53 +01:00
|
|
|
};
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-04-29 13:16:31 +02:00
|
|
|
const ULONG MAX_SORT_RECORD = 65535; /* bytes */
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
/* the record struct actually contains the keyids etc, and the back_pointer
|
2004-03-19 07:14:53 +01:00
|
|
|
which points to the sort_record structure. */
|
2004-06-08 20:27:59 +02:00
|
|
|
struct sr
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2004-03-19 07:14:53 +01:00
|
|
|
sort_record** sr_bckptr; /* Pointer back to sort list entry */
|
|
|
|
sort_record sr_sort_record;
|
2004-06-08 20:27:59 +02:00
|
|
|
};
|
|
|
|
typedef sr SR;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
/* scb_longs includes the size of sr_bckptr. */
|
|
|
|
|
|
|
|
/* The sort memory pool is laid out as follows during sorting:
|
|
|
|
|
|
|
|
struct sort_memory {
|
|
|
|
struct sr *records [X1];
|
|
|
|
ULONG empty [X2];
|
|
|
|
struct sr data [X1];
|
|
|
|
};
|
|
|
|
|
|
|
|
We pack items into sort_memory, inserting the first pointer into
|
|
|
|
records [0], and the first data value into data[X1-1]; Continuing
|
|
|
|
until we are out of records to sort or memory.
|
|
|
|
(eg: X1*(sizeof(struct sr*) + scb->scb_longs) + X2*sizeof(ULONG) == MAX_MEMORY
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
/* Sort key definition block */
|
|
|
|
|
2004-03-11 06:04:26 +01:00
|
|
|
struct sort_key_def
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
UCHAR skd_dtype; /* Data type */
|
|
|
|
UCHAR skd_flags; /* Flags */
|
|
|
|
USHORT skd_length; /* Length if string */
|
|
|
|
USHORT skd_offset; /* Offset from beginning */
|
|
|
|
USHORT skd_vary_offset; /* Offset to varying/cstring length */
|
2004-03-11 06:04:26 +01:00
|
|
|
};
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
/* skd_dtype */
|
|
|
|
|
2004-04-29 13:16:31 +02:00
|
|
|
const int SKD_long = 1;
|
|
|
|
const int SKD_ulong = 2;
|
|
|
|
const int SKD_short = 3;
|
|
|
|
const int SKD_ushort = 4;
|
|
|
|
const int SKD_text = 5;
|
|
|
|
const int SKD_float = 6;
|
|
|
|
const int SKD_double = 7;
|
|
|
|
const int SKD_quad = 8;
|
|
|
|
const int SKD_timestamp1 = 9; /* Timestamp as Float */
|
|
|
|
const int SKD_bytes = 10;
|
|
|
|
const int SKD_d_float = 11;
|
|
|
|
const int SKD_varying = 12; /* non-international */
|
|
|
|
const int SKD_cstring = 13; /* non-international */
|
|
|
|
|
|
|
|
const int SKD_sql_time = 14;
|
|
|
|
const int SKD_sql_date = 15;
|
|
|
|
const int SKD_timestamp2 = 16; /* Timestamp as Quad */
|
|
|
|
|
|
|
|
const int SKD_int64 = 17;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
/* Historical alias for pre V6 code */
|
2004-04-29 13:16:31 +02:00
|
|
|
const int SKD_date = SKD_timestamp1;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
/* skd_flags */
|
|
|
|
|
2004-05-04 00:42:47 +02:00
|
|
|
const UCHAR SKD_ascending = 0; /* default initializer */
|
|
|
|
const UCHAR SKD_descending = 1;
|
|
|
|
const UCHAR SKD_insensitive = 2;
|
|
|
|
const UCHAR SKD_binary = 4;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-04-29 13:16:31 +02:00
|
|
|
const int TYPE_RUN = 0;
|
|
|
|
const int TYPE_MRG = 1;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
/* Run/merge common block header */
|
|
|
|
|
2004-03-28 11:10:30 +02:00
|
|
|
struct run_merge_hdr
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
SSHORT rmh_type; /* TYPE_RUN or TYPE_MRG */
|
2004-03-28 11:10:30 +02:00
|
|
|
merge_control* rmh_parent;
|
|
|
|
};
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
/* Run control block */
|
|
|
|
|
2004-03-19 07:14:53 +01:00
|
|
|
struct run_control
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2004-03-28 11:10:30 +02:00
|
|
|
run_merge_hdr run_header;
|
2004-03-19 07:14:53 +01:00
|
|
|
run_control* run_next; /* Next (actually last) run */
|
2001-05-23 15:26:42 +02:00
|
|
|
ULONG run_records; /* Records (remaining) in run */
|
|
|
|
#ifdef SCROLLABLE_CURSORS
|
|
|
|
ULONG run_max_records; /* total number of records in run */
|
|
|
|
#endif
|
|
|
|
USHORT run_depth; /* Number of "elementary" runs */
|
2004-03-19 07:14:53 +01:00
|
|
|
sort_work_file* run_sfb; /* Run sort file block */
|
2001-05-23 15:26:42 +02:00
|
|
|
ULONG run_seek; /* Offset in file of run */
|
|
|
|
ULONG run_size; /* Length of run in work file */
|
|
|
|
#ifdef SCROLLABLE_CURSORS
|
|
|
|
ULONG run_cached; /* amount of cached data from run file */
|
|
|
|
#endif
|
2004-03-19 07:14:53 +01:00
|
|
|
sort_record* run_record; /* Next record in run */
|
2001-05-23 15:26:42 +02:00
|
|
|
SORTP* run_buffer; /* Run buffer */
|
|
|
|
SORTP* run_end_buffer; /* End of buffer */
|
|
|
|
ULONG run_buff_alloc; /* ALlocated buffer flag */
|
2004-03-19 07:14:53 +01:00
|
|
|
};
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
/* Merge control block */
|
|
|
|
|
2004-03-28 11:10:30 +02:00
|
|
|
struct merge_control
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2004-03-28 11:10:30 +02:00
|
|
|
run_merge_hdr mrg_header;
|
2004-03-19 07:14:53 +01:00
|
|
|
sort_record* mrg_record_a;
|
2004-03-28 11:10:30 +02:00
|
|
|
run_merge_hdr* mrg_stream_a;
|
2004-03-19 07:14:53 +01:00
|
|
|
sort_record* mrg_record_b;
|
2004-03-28 11:10:30 +02:00
|
|
|
run_merge_hdr* mrg_stream_b;
|
|
|
|
};
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
/* Work file space control block */
|
|
|
|
|
2004-03-28 11:10:30 +02:00
|
|
|
struct work_file_space
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2004-03-28 11:10:30 +02:00
|
|
|
work_file_space* wfs_next;
|
|
|
|
ULONG wfs_position; /* Starting position of free space */
|
|
|
|
ULONG wfs_size; /* Length of free space */
|
|
|
|
};
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
/* Sort work file control block */
|
|
|
|
|
2004-03-19 07:14:53 +01:00
|
|
|
struct sort_work_file
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2004-03-19 07:14:53 +01:00
|
|
|
sort_work_file* sfb_next;
|
2001-05-23 15:26:42 +02:00
|
|
|
int sfb_file; /* File descriptor */
|
2004-03-28 11:10:30 +02:00
|
|
|
TEXT* sfb_file_name; /* ALLOC: File name for deletion */
|
2001-05-23 15:26:42 +02:00
|
|
|
ULONG sfb_file_size; /* Real size of the work file */
|
2004-03-28 11:10:30 +02:00
|
|
|
work_file_space* sfb_file_space; /* ALLOC: Available space in work file */
|
|
|
|
work_file_space* sfb_free_wfs; /* ALLOC: Free space in work file */
|
|
|
|
dir_list* sfb_dls; /* Place where file is created */
|
2002-04-29 13:22:26 +02:00
|
|
|
SortMem* sfb_mem;
|
2004-03-19 07:14:53 +01:00
|
|
|
};
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
/* Sort Context Block */
|
2004-03-19 07:14:53 +01:00
|
|
|
// Context or Control???
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-12-22 11:00:59 +01:00
|
|
|
// Used by SORT_init
|
|
|
|
typedef bool (*FPTR_REJECT_DUP_CALLBACK)(const UCHAR*, const UCHAR*, void*);
|
|
|
|
|
2004-03-19 07:14:53 +01:00
|
|
|
struct sort_context
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2004-03-19 07:14:53 +01:00
|
|
|
sort_context* scb_next; /* Next known sort in system */
|
2001-05-23 15:26:42 +02:00
|
|
|
SORTP *scb_memory; /* ALLOC: Memory for sort */
|
|
|
|
SORTP *scb_end_memory; /* End of memory */
|
|
|
|
ULONG scb_size_memory; /* Bytes allocated */
|
|
|
|
SR *scb_last_record; /* Address of last record */
|
2004-03-19 07:14:53 +01:00
|
|
|
sort_record** scb_first_pointer; /* Memory for sort */
|
|
|
|
sort_record** scb_next_pointer; /* Address for next pointer */
|
2001-05-23 15:26:42 +02:00
|
|
|
#ifdef SCROLLABLE_CURSORS
|
|
|
|
SORTP **scb_last_pointer; /* Address for last pointer in block */
|
|
|
|
#endif
|
|
|
|
USHORT scb_length; /* Record length */
|
|
|
|
USHORT scb_longs; /* Length of record in longwords */
|
|
|
|
ULONG scb_keys; /* Number of keys */
|
|
|
|
ULONG scb_key_length; /* Key length */
|
|
|
|
ULONG scb_records; /* Number of records */
|
2003-09-28 20:23:26 +02:00
|
|
|
UINT64 scb_max_records; /* Maximum number of records to store */
|
2004-03-19 07:14:53 +01:00
|
|
|
sort_work_file* scb_sfb; /* ALLOC: List of scratch files, if open */
|
|
|
|
run_control* scb_runs; /* ALLOC: Run on scratch file, if any */
|
2004-03-28 11:10:30 +02:00
|
|
|
merge_control* scb_merge; /* Top level merge block */
|
2004-03-19 07:14:53 +01:00
|
|
|
run_control* scb_free_runs; /* ALLOC: Currently unused run blocks */
|
2003-12-11 11:33:30 +01:00
|
|
|
SORTP* scb_merge_space; /* ALLOC: memory space to do merging */
|
2001-05-23 15:26:42 +02:00
|
|
|
ULONG scb_flags; /* see flag bits below */
|
2003-04-10 08:49:16 +02:00
|
|
|
ISC_STATUS *scb_status_vector; /* Status vector for errors */
|
2003-12-11 11:33:30 +01:00
|
|
|
FPTR_REJECT_DUP_CALLBACK scb_dup_callback; /* Duplicate handling callback */
|
2004-03-28 11:10:30 +02:00
|
|
|
void* scb_dup_callback_arg; /* Duplicate handling callback arg */
|
|
|
|
dir_list* scb_dls;
|
|
|
|
merge_control* scb_merge_pool; /* ALLOC: pool of merge_control blocks */
|
|
|
|
Attachment* scb_attachment; /* back pointer to attachment */
|
|
|
|
irsb_sort* scb_impure; /* back pointer to request's impure area */
|
2004-03-11 06:04:26 +01:00
|
|
|
sort_key_def scb_description[1];
|
2004-03-19 07:14:53 +01:00
|
|
|
};
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
/* flags as set in scb_flags */
|
|
|
|
|
2004-04-29 13:16:31 +02:00
|
|
|
const int scb_initialized = 1;
|
|
|
|
const int scb_sorted = 2; /* stream has been sorted */
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-03-19 07:14:53 +01:00
|
|
|
#define SCB_LEN(n_k) (sizeof (sort_context) + (SLONG)(n_k) * sizeof (sort_key_def))
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-03-20 15:57:40 +01:00
|
|
|
} //namespace Jrd
|
|
|
|
|
2003-11-06 18:57:01 +01:00
|
|
|
#endif // JRD_SORT_H
|
2003-12-11 11:33:30 +01:00
|
|
|
|