|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* Motif
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* Copyright (c) 1987-2012, The Open Group. All rights reserved.
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* These libraries and programs are free software; you can
|
|
Packit |
b099d7 |
* redistribute them and/or modify them under the terms of the GNU
|
|
Packit |
b099d7 |
* Lesser General Public License as published by the Free Software
|
|
Packit |
b099d7 |
* Foundation; either version 2 of the License, or (at your option)
|
|
Packit |
b099d7 |
* any later version.
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* These libraries and programs are distributed in the hope that
|
|
Packit |
b099d7 |
* they will be useful, but WITHOUT ANY WARRANTY; without even the
|
|
Packit |
b099d7 |
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
Packit |
b099d7 |
* PURPOSE. See the GNU Lesser General Public License for more
|
|
Packit |
b099d7 |
* details.
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* You should have received a copy of the GNU Lesser General Public
|
|
Packit |
b099d7 |
* License along with these librararies and programs; if not, write
|
|
Packit |
b099d7 |
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
|
|
Packit |
b099d7 |
* Floor, Boston, MA 02110-1301 USA
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* HISTORY
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
/* $XConsortium: IDB.h /main/11 1995/07/14 10:36:17 drk $ */
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* (c) Copyright 1989, 1990, DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. */
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
#ifndef idb_h
|
|
Packit |
b099d7 |
#define idb_h 1
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* This file defines the constants and structs required by the URM
|
|
Packit |
b099d7 |
* Indexed Data Base facility (IDB). The order of definition is:
|
|
Packit |
b099d7 |
* o literals
|
|
Packit |
b099d7 |
* o primitive typedefs
|
|
Packit |
b099d7 |
* o typedefs for file records
|
|
Packit |
b099d7 |
* o typedefs for in-memory structures
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* IDB literals
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* Primitive typedefs
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* A data pointer. Consists of a record number (of a data record) and an
|
|
Packit |
b099d7 |
* offset in the record to the data entry.
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
typedef union {
|
|
Packit |
b099d7 |
unsigned pointer ; /* the pointer as a value */
|
|
Packit |
b099d7 |
struct {
|
|
Packit |
b099d7 |
IDBRecordNumber rec_no B32 ; /* record number */
|
|
Packit |
b099d7 |
MrmOffset item_offs B32 ; /* offset of data entry in
|
|
Packit |
b099d7 |
record. Must be a
|
|
Packit |
b099d7 |
IDB*DataEntry struct */
|
|
Packit |
b099d7 |
} internal_id ; /* 2 fields internally */
|
|
Packit |
b099d7 |
} IDBDataPointer ;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* A data pointer as a passed-by-value reference
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
#if 0
|
|
Packit |
b099d7 |
typedef unsigned IDBDataHandle ;
|
|
Packit |
b099d7 |
#endif
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
typedef struct {
|
|
Packit |
b099d7 |
IDBRecordNumber rec_no ; /* record number */
|
|
Packit |
b099d7 |
MrmOffset item_offs ; /* offset of data entry in
|
|
Packit |
b099d7 |
record. Must be a
|
|
Packit |
b099d7 |
IDB*DataEntry struct */
|
|
Packit |
b099d7 |
} IDBDataHandle ;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* A data item in a data record.
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* entry types distinguish simple and overflow records
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
#define IDBdrSimple 1
|
|
Packit |
b099d7 |
#define IDBdrOverflow 2
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* Common header for both simple and overflow data entries
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
#define IDBDataEntryValid 222857390
|
|
Packit |
b099d7 |
typedef struct {
|
|
Packit |
b099d7 |
unsigned validation; /* validation code =
|
|
Packit |
b099d7 |
IDBDataEntryValid */
|
|
Packit |
b099d7 |
MrmCode entry_type; /* IDBdrSimple, IDBdrOverflow */
|
|
Packit |
b099d7 |
MrmCode resource_group; /* resource group */
|
|
Packit |
b099d7 |
MrmCode resource_type; /* resource type */
|
|
Packit |
b099d7 |
MrmCode access; /* URMaPrivate or URMaPublic */
|
|
Packit |
b099d7 |
MrmCode lock; /* locking code */
|
|
Packit |
b099d7 |
MrmSize entry_size; /* number of data bytes */
|
|
Packit |
b099d7 |
MrmOffset prev_entry; /* Offset of previous entry in
|
|
Packit |
b099d7 |
this data record. */
|
|
Packit |
b099d7 |
} IDBDataEntryHdr, *IDBDataEntryHdrPtr ;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
#define SwapIDBDataEntryHdr(deh) { \
|
|
Packit |
b099d7 |
swap4bytes(deh->validation); \
|
|
Packit |
b099d7 |
swap2bytes(deh->entry_type) ; \
|
|
Packit |
b099d7 |
swap2bytes(deh->resource_group) ; \
|
|
Packit |
b099d7 |
swap2bytes(deh->resource_type) ; \
|
|
Packit |
b099d7 |
swap2bytes(deh->access) ; \
|
|
Packit |
b099d7 |
swap2bytes(deh->lock) ; \
|
|
Packit |
b099d7 |
swap2bytes(deh->entry_size) ; \
|
|
Packit |
b099d7 |
swap2bytes(deh->prev_entry) ; \
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* A simple data entry
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
typedef struct {
|
|
Packit |
b099d7 |
IDBDataEntryHdr header ; /* common header, entry_type =
|
|
Packit |
b099d7 |
IDBdrSimple */
|
|
Packit |
b099d7 |
char data[1] ; /* First byte in data */
|
|
Packit |
b099d7 |
} IDBSimpleData, *IDBSimpleDataPtr ;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* An overflow data entry. These are used for all data entries which are
|
|
Packit |
b099d7 |
* too big to fit in a single record. These are broken up into 2 or more
|
|
Packit |
b099d7 |
* overflow entries, whose contents are concatenated to produce the
|
|
Packit |
b099d7 |
* actual data entry.
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
typedef struct {
|
|
Packit |
b099d7 |
IDBDataEntryHdr header ; /* common header, entry_type =
|
|
Packit |
b099d7 |
IDBdrOverflow */
|
|
Packit |
b099d7 |
MrmSize segment_size; /* number of data bytes in
|
|
Packit |
b099d7 |
this segment */
|
|
Packit |
b099d7 |
MrmCount segment_count; /* number of records needed
|
|
Packit |
b099d7 |
to store entry */
|
|
Packit |
b099d7 |
MrmCount segment_num; /* this segment's number */
|
|
Packit |
b099d7 |
IDBDataPointer next_segment ; /* next segment */
|
|
Packit |
b099d7 |
char data[1] ; /* first data byte */
|
|
Packit |
b099d7 |
} IDBOverflowData, *IDBOverflowDataPtr ;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
#define SwapIDBOverflowData(doh) { \
|
|
Packit |
b099d7 |
swap2bytes(doh->segment_size) ; \
|
|
Packit |
b099d7 |
swap2bytes(doh->segment_count) ; \
|
|
Packit |
b099d7 |
swap2bytes(doh->segment_num) ; \
|
|
Packit |
b099d7 |
swap2bytes(doh->next_segment.internal_id.rec_no) ; \
|
|
Packit |
b099d7 |
swap2bytes(doh->next_segment.internal_id.item_offs) ; \
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* Header sizes for data entries
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
#define IDBSimpleDataHdrSize (sizeof(IDBSimpleData) - sizeof(char))
|
|
Packit |
b099d7 |
#define IDBOverflowDataHdrSize (sizeof(IDBOverflowData) - sizeof(char))
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* File record definitions
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* IDB uses one size of fixed-length record for all its file records.
|
|
Packit |
b099d7 |
* The size of this record is determined as a reasonable common size
|
|
Packit |
b099d7 |
* which gives efficient disk access on all the file systems on which
|
|
Packit |
b099d7 |
* IDB runs.
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* All records are accessed by record number. These increase monotonically
|
|
Packit |
b099d7 |
* from the lowest valid record number, which is maintained in the file
|
|
Packit |
b099d7 |
* header.
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* IDB defines the following types of records:
|
|
Packit |
b099d7 |
* Header - one per file
|
|
Packit |
b099d7 |
* Index leaf - contains leaf nodes of the B-tree index
|
|
Packit |
b099d7 |
* Index node - contains non-leaf nodes of the B-tree index
|
|
Packit |
b099d7 |
* RID map - contains pointers which map IDB resourc IDs to
|
|
Packit |
b099d7 |
* data block pointers
|
|
Packit |
b099d7 |
* Data - Contains data blocks
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* All records have a common record header which gives the record number
|
|
Packit |
b099d7 |
* and record type. This header and the information for each record type
|
|
Packit |
b099d7 |
* are defined below.
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* Number of bytes in a low-level file block = # bytes in an IDB file record
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
#define IDBRecordSize 4096
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* IDB record header
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
#define IDBRecordHeaderValid 310144882
|
|
Packit |
b099d7 |
typedef struct {
|
|
Packit |
b099d7 |
unsigned validation; /* validation code =
|
|
Packit |
b099d7 |
IDBRecordHeaderValid */
|
|
Packit |
b099d7 |
MrmType record_type; /* record type */
|
|
Packit |
b099d7 |
IDBRecordNumber record_num; /* IDB record number */
|
|
Packit |
b099d7 |
} IDBRecordHeader, *IDBRecordHeaderPtr ;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* Dummy IDB record.
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
typedef struct {
|
|
Packit |
b099d7 |
IDBRecordHeader header ;
|
|
Packit |
b099d7 |
char dummy[IDBRecordSize-sizeof(IDBRecordHeader)] ;
|
|
Packit |
b099d7 |
} IDBDummyRecord, *IDBDummyRecordPtr ;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* IDB header record definition
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* There is one header record per IDB file. It is the only record in the
|
|
Packit |
b099d7 |
* which must be at a fixed location; its record number is
|
|
Packit |
b099d7 |
* IDBHeaderRecordNumber.
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* The header contains the following:
|
|
Packit |
b099d7 |
* o Information about how the file was created
|
|
Packit |
b099d7 |
* o A pointer to the root node record for the B-tree index
|
|
Packit |
b099d7 |
* o The next available resourc id (RID)
|
|
Packit |
b099d7 |
* o An end-of-file pointer (record number of last record in file)
|
|
Packit |
b099d7 |
* o Counters of the number of index and RID entries in the file
|
|
Packit |
b099d7 |
* o Counter of the different types of records in the file
|
|
Packit |
b099d7 |
* o The remainder of the record is used as the initial space in
|
|
Packit |
b099d7 |
* which to allocate a small RID map and data entries. This
|
|
Packit |
b099d7 |
* enables relatively small files to be created when a small
|
|
Packit |
b099d7 |
* amount of information will be stored, as the minimal file
|
|
Packit |
b099d7 |
* need contain only a header and (probably) and index leaf record
|
|
Packit |
b099d7 |
* rather than also requiring an RID map record and a data record.
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* IDB file header record header
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
typedef struct {
|
|
Packit |
b099d7 |
IDBRecordHeader header ; /* record_type =
|
|
Packit |
b099d7 |
IDBrtHeader,
|
|
Packit |
b099d7 |
record_num =
|
|
Packit |
b099d7 |
IDBrtHeader, */
|
|
Packit |
b099d7 |
char db_version[IDBhsVersion1] ;
|
|
Packit |
b099d7 |
/* database version */
|
|
Packit |
b099d7 |
char creator[IDBhsCreator1] ; /* creator id */
|
|
Packit |
b099d7 |
char creator_version[IDBhsVersion1] ;
|
|
Packit |
b099d7 |
/* creator version */
|
|
Packit |
b099d7 |
char creation_date[IDBhsDate1] ;
|
|
Packit |
b099d7 |
/* creation date */
|
|
Packit |
b099d7 |
char module[IDBhsModule1] ; /* module id */
|
|
Packit |
b099d7 |
char module_version[IDBhsVersion1] ;
|
|
Packit |
b099d7 |
/* module version */
|
|
Packit |
b099d7 |
IDBRecordNumber index_root ; /* index root pointer */
|
|
Packit |
b099d7 |
MrmCount num_indexed ; /* # entries in index */
|
|
Packit |
b099d7 |
MrmCount num_RID ; /* # RID entries in file */
|
|
Packit |
b099d7 |
IDBridDesc next_RID ; /* next available RID. */
|
|
Packit |
b099d7 |
IDBRecordNumber last_record ; /* last record used in file */
|
|
Packit |
b099d7 |
IDBRecordNumber last_data_record ; /* last data record in file */
|
|
Packit |
b099d7 |
MrmCount group_counts[URMgVecSize] ;
|
|
Packit |
b099d7 |
/* vector of record counts
|
|
Packit |
b099d7 |
by resource group */
|
|
Packit |
b099d7 |
MrmCount rt_counts[IDBrtVecSize] ;
|
|
Packit |
b099d7 |
/* vector of record counts by
|
|
Packit |
b099d7 |
record type (statistics) */
|
|
Packit |
b099d7 |
} IDBHeaderHdr, *IDBHeaderHdrPtr ;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* IDB file header record
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* Max number of entries in RID pointer vector
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
#define IDBHeaderRIDMax 20
|
|
Packit |
b099d7 |
typedef struct {
|
|
Packit |
b099d7 |
IDBHeaderHdr header_hdr ; /* header part */
|
|
Packit |
b099d7 |
IDBDataPointer RID_pointers[IDBHeaderRIDMax];
|
|
Packit |
b099d7 |
/* RID pointer vector */
|
|
Packit |
b099d7 |
MrmCount num_entry; /* number of entries in record */
|
|
Packit |
b099d7 |
MrmOffset last_entry; /* last entry in page */
|
|
Packit |
b099d7 |
MrmOffset free_ptr; /* offset of first free byte.
|
|
Packit |
b099d7 |
initial value = 0 */
|
|
Packit |
b099d7 |
MrmCount free_count; /* number of free bytes. Initial
|
|
Packit |
b099d7 |
value = IDBHeaderFreeMax */
|
|
Packit |
b099d7 |
char data[1]; /* First available byte for data */
|
|
Packit |
b099d7 |
} IDBHeaderRecord, *IDBHeaderRecordPtr ;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* Free space in header record, max number of bytes available for data.
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
#define IDBHeaderFreeMax (IDBRecordSize-sizeof(IDBHeaderRecord)+sizeof(char))
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* Record number of the header record
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
#define IDBHeaderRecordNumber 1
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* Index leaf record definition
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* IDB provides two mutually exclusive mechanisms for accessing data.
|
|
Packit |
b099d7 |
* The first is an index system based on ASCII keys (indexes). This
|
|
Packit |
b099d7 |
* uses a B-tree index as its lookup mechanism. The second mechanism
|
|
Packit |
b099d7 |
* is a resource id mechanism offering potentially faster access, as
|
|
Packit |
b099d7 |
* described below.
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* As usual in B-tree systems, the B-tree index has two kinds of nodes:
|
|
Packit |
b099d7 |
* leaf nodes, which contain only data pointers, and B-tree nodes,
|
|
Packit |
b099d7 |
* which contain pointers to other B-tree records. The following describes
|
|
Packit |
b099d7 |
* leaf records in the B-tree index.
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* The root node of the index is a leaf record if there is exactly 1
|
|
Packit |
b099d7 |
* record in the index, and is a tree node otherwise.
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* A leaf record consists of a sorted vector of index entries, ordered
|
|
Packit |
b099d7 |
* in increasing alphabetical order by the index value. The vector
|
|
Packit |
b099d7 |
* contains fixed-length entries, with the key strings being allocated
|
|
Packit |
b099d7 |
* at the bottom of the record. The vector grows down from the top and
|
|
Packit |
b099d7 |
* the string heap up from the bottom as entries are added, until the
|
|
Packit |
b099d7 |
* record fills.
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* An entry in the index vector
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
typedef struct {
|
|
Packit |
b099d7 |
MrmOffset index_stg; /* offset of the index string in
|
|
Packit |
b099d7 |
the record. Nul-terminated. */
|
|
Packit |
b099d7 |
IDBDataPointer data ; /* pointer to the data entry */
|
|
Packit |
b099d7 |
} IDBIndexLeafEntry, *IDBIndexLeafEntryPtr ;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* Size of an index vector entry
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
#define IDBIndexLeafEntrySize sizeof(IDBIndexLeafEntry)
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* Max length of an index string (terminating nul not included)
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
#define IDBMaxIndexLength URMMaxIndexLen
|
|
Packit |
b099d7 |
#define IDBMaxIndexLength1 (IDBMaxIndexLength + 1)
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* Leaf record header
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
typedef struct {
|
|
Packit |
b099d7 |
IDBRecordHeader header ; /* record_type = IDBrtIndexLeaf */
|
|
Packit |
b099d7 |
IDBRecordNumber parent; /* B-tree parent record */
|
|
Packit |
b099d7 |
MrmCount index_count; /* Number of index entries in record */
|
|
Packit |
b099d7 |
MrmOffset heap_start; /* Offset of first byte in use for
|
|
Packit |
b099d7 |
index string heap storage. Offset
|
|
Packit |
b099d7 |
is from .index[0] */
|
|
Packit |
b099d7 |
MrmCount free_bytes; /* Number of free bytes in record */
|
|
Packit |
b099d7 |
} IDBIndexLeafHdr, *IDBIndexLeafHdrPtr ;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* The leaf record
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
typedef struct {
|
|
Packit |
b099d7 |
IDBIndexLeafHdr leaf_header ; /* header part of record. Initial
|
|
Packit |
b099d7 |
values: heap_start =
|
|
Packit |
b099d7 |
free_bytes = IDBIndexLeafFreeMax */
|
|
Packit |
b099d7 |
IDBIndexLeafEntry index[1] ; /* First entry in index vector. There
|
|
Packit |
b099d7 |
are index_count entries. */
|
|
Packit |
b099d7 |
} IDBIndexLeafRecord, *IDBIndexLeafRecordPtr ;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* Max number of free bytes in leaf index record (0 entries)
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
#define IDBIndexLeafFreeMax (IDBRecordSize - sizeof(IDBIndexLeafHdr))
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* Index B-tree node record definition
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* A B-tree node record is similar to a leaf entry, except that each node
|
|
Packit |
b099d7 |
* contains a pair of pointers to other nodes in the tree; one to a LT
|
|
Packit |
b099d7 |
* node, all of whose entries order < the entry's index; one to a GT node,
|
|
Packit |
b099d7 |
* all of whose entries order > the entry's index. The GT pointer of node
|
|
Packit |
b099d7 |
* m = the LT pointer of node m+1. Thus any node record containing n nodes
|
|
Packit |
b099d7 |
* points to n+1 tree nodes. Allocation of heap for index strings is as in
|
|
Packit |
b099d7 |
* a leaf record. All entries also locate a data entry.
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* An entry in the index vector
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
typedef struct {
|
|
Packit |
b099d7 |
MrmOffset index_stg; /* offset of the index string in
|
|
Packit |
b099d7 |
the record. Nul-terminated. */
|
|
Packit |
b099d7 |
IDBDataPointer data ; /* pointer to the data entry */
|
|
Packit |
b099d7 |
IDBRecordNumber LT_record; /* pointer to LT record */
|
|
Packit |
b099d7 |
IDBRecordNumber GT_record; /* pointer to GT record */
|
|
Packit |
b099d7 |
} IDBIndexNodeEntry, *IDBIndexNodeEntryPtr ;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* Size of an index vector entry
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
#define IDBIndexNodeEntrySize sizeof(IDBIndexNodeEntry)
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* Node record header
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
typedef struct {
|
|
Packit |
b099d7 |
IDBRecordHeader header ; /* record_type = IDBrtIndexNode */
|
|
Packit |
b099d7 |
IDBRecordNumber parent; /* B-tree parent record */
|
|
Packit |
b099d7 |
MrmCount index_count; /* Number of index entries in record */
|
|
Packit |
b099d7 |
MrmOffset heap_start; /* Offset of first byte in use for
|
|
Packit |
b099d7 |
index string heap storage. Offset
|
|
Packit |
b099d7 |
is from .index[0] */
|
|
Packit |
b099d7 |
MrmCount free_bytes; /* Number of free bytes in record */
|
|
Packit |
b099d7 |
} IDBIndexNodeHdr, *IDBIndexNodeHdrPtr ;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* The B-tree node entry
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
typedef struct {
|
|
Packit |
b099d7 |
IDBIndexNodeHdr node_header ; /* header part of record. Initial
|
|
Packit |
b099d7 |
values: heap_start =
|
|
Packit |
b099d7 |
free_bytes = IDBIndexNodeFreeMax */
|
|
Packit |
b099d7 |
IDBIndexNodeEntry index[1] ; /* First entry in index vector. There
|
|
Packit |
b099d7 |
are index_count entries. */
|
|
Packit |
b099d7 |
} IDBIndexNodeRecord, *IDBIndexNodeRecordPtr ;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* Max number of free bytes in node index record (0 entries)
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
#define IDBIndexNodeFreeMax (IDBRecordSize - sizeof(IDBIndexNodeHdr))
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* Max number of bytes consumed by a new entry
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
#define IDBIndexNodeEntryMax (IDBMaxIndexLength1 + IDBIndexNodeEntrySize \
|
|
Packit |
b099d7 |
+ sizeof(IDBRecordNumber))
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* Resource ID record
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* RID records locate the data block associated with a given resource ID.
|
|
Packit |
b099d7 |
* Looking up a data block accessed by RID is a two-step process:
|
|
Packit |
b099d7 |
* 1. The index map in the file header (maintained in-memory for open
|
|
Packit |
b099d7 |
* files) is used to locate the correct resource ID record. The
|
|
Packit |
b099d7 |
* map_index field in a RID descriptor accesses this record via
|
|
Packit |
b099d7 |
* the RID_maps vector in the header.
|
|
Packit |
b099d7 |
* 2. The Resource ID record supplies the data block pointer. The
|
|
Packit |
b099d7 |
* data block pointer is found in the resource_ptr vector using the
|
|
Packit |
b099d7 |
* res_index field of the RID descriptor.
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* Aside from the standard record header, an RID record contains only
|
|
Packit |
b099d7 |
* a vector of data block pointer.
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* The RID map record header
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
typedef struct {
|
|
Packit |
b099d7 |
IDBRecordHeader header ; /* record type = IDBrdRIDMap */
|
|
Packit |
b099d7 |
} IDBridMapHdr, *IDBridMapHdrPtr ;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* The RID map record is a vector of data pointers
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
typedef struct {
|
|
Packit |
b099d7 |
IDBridMapHdr map_header ; /* Header part of record */
|
|
Packit |
b099d7 |
IDBDataPointer pointers[1] ; /* First pointer in vector. */
|
|
Packit |
b099d7 |
} IDBridMapRecord, *IDBridMapRecordPtr ;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* Max number of free bytes, number of vector entries in RID record
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
#define IDBridFreeMax (IDBRecordSize - sizeof(IDBridMapHdr))
|
|
Packit |
b099d7 |
#define IDBridPtrVecMax (IDBridFreeMax / sizeof(IDBDataPointer))
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* Data record
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* Data records hold data entries. The record maintains a free space
|
|
Packit |
b099d7 |
* pointer, but otherwise contains little information. IDB attempts
|
|
Packit |
b099d7 |
* to avoid splitting data entries into segments, and is thus willing
|
|
Packit |
b099d7 |
* to waste some space in a data record if a data item will fit in
|
|
Packit |
b099d7 |
* a new record.
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* All the data entries in a record are chained via the prev_entry offset
|
|
Packit |
b099d7 |
* field. This is for the convenience of the dump routines. The first
|
|
Packit |
b099d7 |
* entry is always at offset 0 (= initial value of free ptr).
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* The data record header
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
typedef struct {
|
|
Packit |
b099d7 |
IDBRecordHeader header ; /* record = IDBrtData */
|
|
Packit |
b099d7 |
MrmCount num_entry; /* number of entries in record */
|
|
Packit |
b099d7 |
MrmOffset last_entry; /* last entry in page */
|
|
Packit |
b099d7 |
MrmOffset free_ptr; /* offset of first free byte.
|
|
Packit |
b099d7 |
initial value = 0 */
|
|
Packit |
b099d7 |
MrmCount free_count; /* number of free bytes. Initial
|
|
Packit |
b099d7 |
value = IDBDataFreeMax */
|
|
Packit |
b099d7 |
} IDBDataHdr, *IDBDataHdrPtr ;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* The data record
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
typedef struct {
|
|
Packit |
b099d7 |
IDBDataHdr data_header ; /* Header part of record. Initial
|
|
Packit |
b099d7 |
values: free_ptr = &.data[0],
|
|
Packit |
b099d7 |
free_count = IDBDataFreeMax */
|
|
Packit |
b099d7 |
char data[1] ; /* First available byte for data */
|
|
Packit |
b099d7 |
} IDBDataRecord, *IDBDataRecordPtr ;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* Max number of free bytes in data record
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
#define IDBDataFreeMax (IDBRecordSize - sizeof(IDBDataHdr))
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* Max number of bytes of data which can be stored as simple or overflow
|
|
Packit |
b099d7 |
* entries in a data record.
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
#define IDBDataSimpleMax (IDBDataFreeMax - IDBSimpleDataHdrSize)
|
|
Packit |
b099d7 |
#define IDBDataOverflowMax (IDBDataFreeMax - IDBOverflowDataHdrSize)
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* In-memory definitions
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* The following structs are used to save runtime informtion used
|
|
Packit |
b099d7 |
* by IDB. These definitions cover file management and buffer management.
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* The IDBOpenFile/IDBFile struct is defined in Mrm.h
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* Buffer management
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* IDB manages a pool of record buffers which is shared among all open
|
|
Packit |
b099d7 |
* IDB files. All access to these buffers is via the IDB buffer manager,
|
|
Packit |
b099d7 |
* which must be used in all requests to access these buffers for
|
|
Packit |
b099d7 |
* either reading or writing.
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* IDB buffer header
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
#define IDBRecordBufferValid 327711354
|
|
Packit |
b099d7 |
typedef struct {
|
|
Packit |
b099d7 |
unsigned validation ; /* validation code =
|
|
Packit |
b099d7 |
IDBRecordBufferValid */
|
|
Packit |
b099d7 |
long int activity ; /* activity count to determine
|
|
Packit |
b099d7 |
moldiest buffer */
|
|
Packit |
b099d7 |
IDBFile cur_file ; /* file which currently owns buffer */
|
|
Packit |
b099d7 |
MrmCode access ; /* URMReadAccess or URMWriteAccess */
|
|
Packit |
b099d7 |
MrmCode modified ; /* t if buffer has been modified */
|
|
Packit |
b099d7 |
IDBDummyRecord *IDB_record ; /* record in buffer */
|
|
Packit |
b099d7 |
} IDBRecordBuffer, *IDBRecordBufferPtr ;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* Macro which validates a buffer
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
#define Idb__BM_Valid(bufptr) ((bufptr)->validation==IDBRecordBufferValid)
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* Macros which return the record type, number of the record in a buffer
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
#define _IdbBufferRecordType(bufptr) ((bufptr)->IDB_record->header.record_type)
|
|
Packit |
b099d7 |
#define _IdbBufferRecordNumber(bufptr) ((bufptr)->IDB_record->header.record_num)
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
#endif /* idb_h */
|
|
Packit |
b099d7 |
/* DON'T ADD STUFF AFTER THIS #endif */
|