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): ______________________________________.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef _JRD_SORT_H_
|
|
|
|
#define _JRD_SORT_H_
|
|
|
|
|
|
|
|
#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"
|
|
|
|
|
2002-11-17 16:51:25 +01:00
|
|
|
// Forward declaration
|
2002-04-29 13:22:26 +02:00
|
|
|
class SortMem;
|
2001-12-24 03:51:06 +01:00
|
|
|
|
2001-05-23 15:26:42 +02:00
|
|
|
#ifdef __cplusplus
|
|
|
|
extern "C" {
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* 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;
|
|
|
|
|
|
|
|
#define MAX_SORTP ((SORTP) MAX_ULONG)
|
|
|
|
#define MIN_SORTP ((SORTP) MIN_ULONG)
|
|
|
|
|
|
|
|
/* following defines are used to signify whether initial segment in sort key
|
|
|
|
* is for NULL value */
|
|
|
|
#define SORTP_VAL_IS_NULL MAX_SORTP
|
|
|
|
#define SORTP_VAL_IS_NOT_NULL MIN_SORTP
|
|
|
|
|
|
|
|
/* since the first part of the record contains a back_pointer, whose
|
|
|
|
size depends on the platform (ie 16, 32 or 64 bits.).
|
|
|
|
This pointer data_type is defined by platform specific SORT_PTR.
|
|
|
|
*/
|
|
|
|
|
|
|
|
typedef IPTR SORT_PTR;
|
|
|
|
|
|
|
|
/* # 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. */
|
|
|
|
|
|
|
|
typedef struct sort_record
|
|
|
|
{
|
|
|
|
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)
|
|
|
|
*/
|
|
|
|
|
|
|
|
} SORT_RECORD;
|
|
|
|
|
|
|
|
#define MAX_SORT_RECORD 65535 /* bytes */
|
|
|
|
|
|
|
|
/* the record struct actually contains the keyids etc, and the back_pointer
|
|
|
|
which points to the SORT_RECORD structure. */
|
|
|
|
typedef struct sr
|
|
|
|
{
|
2003-02-28 14:38:30 +01:00
|
|
|
struct sort_record **sr_bckptr; /* Pointer back to sort list entry */
|
2001-05-23 15:26:42 +02:00
|
|
|
struct sort_record sr_sort_record;
|
|
|
|
} SR;
|
|
|
|
|
|
|
|
/* 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 */
|
|
|
|
|
|
|
|
typedef struct skd
|
|
|
|
{
|
|
|
|
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 */
|
|
|
|
} SKD;
|
|
|
|
|
|
|
|
/* skd_dtype */
|
|
|
|
|
|
|
|
#define SKD_long 1
|
|
|
|
#define SKD_ulong 2
|
|
|
|
#define SKD_short 3
|
|
|
|
#define SKD_ushort 4
|
|
|
|
#define SKD_text 5
|
|
|
|
#define SKD_float 6
|
|
|
|
#define SKD_double 7
|
|
|
|
#define SKD_quad 8
|
|
|
|
#define SKD_timestamp1 9 /* Timestamp as Float */
|
|
|
|
#define SKD_bytes 10
|
|
|
|
#define SKD_d_float 11
|
|
|
|
#define SKD_varying 12 /* non-international */
|
|
|
|
#define SKD_cstring 13 /* non-international */
|
|
|
|
|
|
|
|
#define SKD_sql_time 14
|
|
|
|
#define SKD_sql_date 15
|
|
|
|
#define SKD_timestamp2 16 /* Timestamp as Quad */
|
|
|
|
|
|
|
|
#define SKD_int64 17
|
|
|
|
|
|
|
|
/* Historical alias for pre V6 code */
|
|
|
|
#define SKD_date SKD_timestamp1
|
|
|
|
|
|
|
|
/* skd_flags */
|
|
|
|
|
|
|
|
#define SKD_ascending 0 /* default initializer */
|
|
|
|
#define SKD_descending 1
|
|
|
|
#define SKD_insensitive 2
|
|
|
|
#define SKD_binary 4
|
|
|
|
|
|
|
|
#define TYPE_RUN 0
|
|
|
|
#define TYPE_MRG 1
|
|
|
|
|
|
|
|
/* Run/merge common block header */
|
|
|
|
|
|
|
|
typedef struct rmh
|
|
|
|
{
|
|
|
|
SSHORT rmh_type; /* TYPE_RUN or TYPE_MRG */
|
|
|
|
struct mrg* rmh_parent;
|
|
|
|
} *RMH;
|
|
|
|
|
|
|
|
/* Run control block */
|
|
|
|
|
|
|
|
typedef struct run
|
|
|
|
{
|
|
|
|
struct rmh run_header;
|
|
|
|
struct run* run_next; /* Next (actually last) run */
|
|
|
|
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 */
|
|
|
|
struct sfb* run_sfb; /* Run sort file block */
|
|
|
|
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
|
|
|
|
SORT_RECORD*run_record; /* Next record in run */
|
|
|
|
SORTP* run_buffer; /* Run buffer */
|
|
|
|
SORTP* run_end_buffer; /* End of buffer */
|
|
|
|
ULONG run_buff_alloc; /* ALlocated buffer flag */
|
|
|
|
} *RUN;
|
|
|
|
|
|
|
|
/* Merge control block */
|
|
|
|
|
|
|
|
typedef struct mrg
|
|
|
|
{
|
|
|
|
struct rmh mrg_header;
|
|
|
|
SORT_RECORD* mrg_record_a;
|
|
|
|
struct rmh* mrg_stream_a;
|
|
|
|
SORT_RECORD* mrg_record_b;
|
|
|
|
struct rmh* mrg_stream_b;
|
|
|
|
} *MRG;
|
|
|
|
|
|
|
|
/* Work file space control block */
|
|
|
|
|
|
|
|
typedef struct wfs
|
|
|
|
{
|
|
|
|
struct wfs* wfs_next;
|
|
|
|
ULONG wfs_position; /* Starting position of free space */
|
|
|
|
ULONG wfs_size; /* Length of free space */
|
|
|
|
} *WFS;
|
|
|
|
|
|
|
|
/* Sort work file control block */
|
|
|
|
|
|
|
|
typedef struct sfb
|
|
|
|
{
|
|
|
|
struct sfb *sfb_next;
|
|
|
|
int sfb_file; /* File descriptor */
|
|
|
|
TEXT *sfb_file_name; /* ALLOC: File name for deletion */
|
|
|
|
ULONG sfb_file_size; /* Real size of the work file */
|
|
|
|
struct wfs *sfb_file_space; /* ALLOC: Available space in work file */
|
|
|
|
struct wfs *sfb_free_wfs; /* ALLOC: Free space in work file */
|
|
|
|
DLS sfb_dls; /* Place where file is created */
|
2002-04-29 13:22:26 +02:00
|
|
|
SortMem* sfb_mem;
|
2001-05-23 15:26:42 +02:00
|
|
|
} *SFB;
|
|
|
|
|
|
|
|
/* Sort Context Block */
|
|
|
|
|
|
|
|
typedef struct scb
|
|
|
|
{
|
|
|
|
struct scb *scb_next; /* Next known sort in system */
|
|
|
|
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 */
|
|
|
|
SORT_RECORD **scb_first_pointer; /* Memory for sort */
|
|
|
|
SORT_RECORD **scb_next_pointer; /* Address for next pointer */
|
|
|
|
#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 */
|
2002-11-16 18:41:12 +01:00
|
|
|
ULONG scb_max_records; /* Maximum number of records to store */
|
2001-05-23 15:26:42 +02:00
|
|
|
struct sfb *scb_sfb; /* ALLOC: List of scratch files, if open */
|
|
|
|
struct run *scb_runs; /* ALLOC: Run on scratch file, if any */
|
|
|
|
struct mrg *scb_merge; /* Top level merge block */
|
|
|
|
struct run *scb_free_runs; /* ALLOC: Currently unused run blocks */
|
|
|
|
SORTP *scb_merge_space; /* ALLOC: memory space to do merging */
|
|
|
|
ULONG scb_run_start; /* Record number of run */
|
|
|
|
ULONG scb_flags; /* see flag bits below */
|
|
|
|
STATUS *scb_status_vector; /* Status vector for errors */
|
|
|
|
BOOLEAN(*scb_dup_callback) (); /* Duplicate handling callback */
|
|
|
|
void *scb_dup_callback_arg; /* Duplicate handling callback arg */
|
|
|
|
struct dls *scb_dls;
|
|
|
|
struct mrg *scb_merge_pool; /* ALLOC: pool of mrg blocks */
|
2001-12-24 03:51:06 +01:00
|
|
|
class att *scb_attachment; /* back pointer to attachment */
|
2001-05-23 15:26:42 +02:00
|
|
|
SKD scb_description[1];
|
|
|
|
} *SCB;
|
|
|
|
|
|
|
|
/* flags as set in scb_flags */
|
|
|
|
|
|
|
|
#define scb_initialized 1
|
|
|
|
#define scb_sorted 2 /* stream has been sorted */
|
|
|
|
|
|
|
|
#define SCB_LEN(n_k) (sizeof (struct scb) + (SLONG)(n_k) * sizeof (SKD))
|
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
} /* extern "C" */
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#endif /* _JRD_SORT_H_ */
|