|
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 |
#ifdef HAVE_CONFIG_H
|
|
Packit |
b099d7 |
#include <config.h>
|
|
Packit |
b099d7 |
#endif
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
#ifdef REV_INFO
|
|
Packit |
b099d7 |
#ifndef lint
|
|
Packit |
b099d7 |
static char rcsid[] = "$XConsortium: MrmIindex.c /main/13 1996/11/13 13:57:31 drk $"
|
|
Packit |
b099d7 |
#endif
|
|
Packit |
b099d7 |
#endif
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* (c) Copyright 1989, 1990, DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. */
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
*++
|
|
Packit |
b099d7 |
* FACILITY:
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* UIL Resource Manager (URM): IDB Facility
|
|
Packit |
b099d7 |
* Index management routines
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* ABSTRACT:
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* These routines manage the index of an IDB file, including entering
|
|
Packit |
b099d7 |
* data entries accessed by index. These routines are read or common
|
|
Packit |
b099d7 |
* (used by both read and writing (MrmIindexw.c)).
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
*--
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* INCLUDE FILES
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
#include <Mrm/MrmAppl.h>
|
|
Packit |
b099d7 |
#include <Mrm/Mrm.h>
|
|
Packit |
b099d7 |
#include <Mrm/IDB.h>
|
|
Packit |
b099d7 |
#include "MrmMsgI.h"
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* TABLE OF CONTENTS
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* Idb__INX_ReturnItem - Return the data entry for an index
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* Idb__INX_FindIndex - Search the index
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* Idb__INX_SearchIndex - Search a record for an index
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* Idb__INX_GetBTreeRecord - Read a record in the B-tree
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* Idb__INX_FindResources - Search the index for resources
|
|
Packit |
b099d7 |
* matching the filter
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* DEFINE and MACRO DEFINITIONS
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* Macros which validate index records in buffers
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
#define Idb__INX_ValidLeaf(buffer) \
|
|
Packit |
b099d7 |
(_IdbBufferRecordType(buffer)==IDBrtIndexLeaf)
|
|
Packit |
b099d7 |
#define Idb__INX_ValidNode(buffer) \
|
|
Packit |
b099d7 |
(_IdbBufferRecordType(buffer)==IDBrtIndexNode)
|
|
Packit |
b099d7 |
#define Idb__INX_ValidRecord(buffer) \
|
|
Packit |
b099d7 |
(_IdbBufferRecordType(buffer)==IDBrtIndexLeaf || \
|
|
Packit |
b099d7 |
_IdbBufferRecordType(buffer)==IDBrtIndexNode)
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
*++
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* PROCEDURE DESCRIPTION:
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* Idb__INX_ReturnItem locates a data entry in the file, and returns
|
|
Packit |
b099d7 |
* the data entry pointer (without reading the data record).
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* FORMAL PARAMETERS:
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* file_id Open IDB file in which to write entry
|
|
Packit |
b099d7 |
* index The entry's case-sensitive index
|
|
Packit |
b099d7 |
* data_entry To return data entry pointer for data
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* IMPLICIT INPUTS:
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* IMPLICIT OUTPUTS:
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* FUNCTION VALUE:
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* MrmSUCCESS operation succeeded
|
|
Packit |
b099d7 |
* MrmFAILURE some other failure
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* SIDE EFFECTS:
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
*--
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
Cardinal
|
|
Packit |
b099d7 |
Idb__INX_ReturnItem (IDBFile file_id,
|
|
Packit |
b099d7 |
char *index,
|
|
Packit |
b099d7 |
IDBDataHandle *data_entry)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* Local variables
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
Cardinal result ; /* function results */
|
|
Packit |
b099d7 |
IDBRecordBufferPtr bufptr ; /* buffer containing entry */
|
|
Packit |
b099d7 |
MrmCount entndx ; /* entry index */
|
|
Packit |
b099d7 |
IDBIndexLeafRecordPtr leafrec ; /* index leaf record */
|
|
Packit |
b099d7 |
IDBIndexNodeRecordPtr noderec ; /* index node record */
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* Attempt to find the index
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
result = Idb__INX_FindIndex (file_id, index, &bufptr, &entndx) ;
|
|
Packit |
b099d7 |
switch ( result )
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
case MrmINDEX_GT:
|
|
Packit |
b099d7 |
case MrmINDEX_LT:
|
|
Packit |
b099d7 |
return MrmNOT_FOUND ;
|
|
Packit |
b099d7 |
case MrmSUCCESS:
|
|
Packit |
b099d7 |
break ;
|
|
Packit |
b099d7 |
default:
|
|
Packit |
b099d7 |
return result ;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* Point into the buffer, and retrieve the data pointer
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
switch ( _IdbBufferRecordType (bufptr) )
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
case IDBrtIndexLeaf:
|
|
Packit |
b099d7 |
leafrec = (IDBIndexLeafRecordPtr) bufptr->IDB_record ;
|
|
Packit |
b099d7 |
data_entry->rec_no = leafrec->index[entndx].data.internal_id.rec_no ;
|
|
Packit |
b099d7 |
data_entry->item_offs =
|
|
Packit |
b099d7 |
leafrec->index[entndx].data.internal_id.item_offs ;
|
|
Packit |
b099d7 |
return MrmSUCCESS ;
|
|
Packit |
b099d7 |
case IDBrtIndexNode:
|
|
Packit |
b099d7 |
noderec = (IDBIndexNodeRecordPtr) bufptr->IDB_record ;
|
|
Packit |
b099d7 |
data_entry->rec_no = noderec->index[entndx].data.internal_id.rec_no ;
|
|
Packit |
b099d7 |
data_entry->item_offs =
|
|
Packit |
b099d7 |
noderec->index[entndx].data.internal_id.item_offs ;
|
|
Packit |
b099d7 |
return MrmSUCCESS ;
|
|
Packit |
b099d7 |
default:
|
|
Packit |
b099d7 |
return Urm__UT_Error ("Idb__INX_ReturnItem", _MrmMMsg_0010,
|
|
Packit |
b099d7 |
file_id, NULL, MrmBAD_RECORD) ;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
*++
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* PROCEDURE DESCRIPTION:
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* Idb__INX_FindIndex finds the index record containing an index entry,
|
|
Packit |
b099d7 |
* and returns the buffer containing that record. It is used both as the
|
|
Packit |
b099d7 |
* low-level routine for locating an index for retrieving a data entry,
|
|
Packit |
b099d7 |
* and for locating the record in which a new index should be inserted.
|
|
Packit |
b099d7 |
* Thus the interpretation of the return code is:
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* MrmSUCCESS found the index, the index record is in the buffer
|
|
Packit |
b099d7 |
* and the index_return locates the entry
|
|
Packit |
b099d7 |
* MrmINDEX_GT buffer contains the leaf index record which should
|
|
Packit |
b099d7 |
* MrmINDEX_LT contain the index, and index_return locates the entry
|
|
Packit |
b099d7 |
* in the buffer at which search terminated. The result
|
|
Packit |
b099d7 |
* value indicates how the given index orders against
|
|
Packit |
b099d7 |
* the entry in index_return.
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* FORMAL PARAMETERS:
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* file_id Open IDB file in which to find index
|
|
Packit |
b099d7 |
* index Case-sensitive index string
|
|
Packit |
b099d7 |
* buffer_return To return pointer to buffer containing index record
|
|
Packit |
b099d7 |
* index_return To return item's index in the records index vector
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* IMPLICIT INPUTS:
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* IMPLICIT OUTPUTS:
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* FUNCTION VALUE:
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* MrmSUCCESS operation succeeded
|
|
Packit |
b099d7 |
* MrmINDEX_GT index not found, but orders greater-than entry at
|
|
Packit |
b099d7 |
* index_return
|
|
Packit |
b099d7 |
* MrmINDEX_LT index not found, but orders less-than entry at
|
|
Packit |
b099d7 |
* index_return
|
|
Packit |
b099d7 |
* MrmFAILURE some other failure
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* SIDE EFFECTS:
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
*--
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
Cardinal
|
|
Packit |
b099d7 |
Idb__INX_FindIndex (IDBFile file_id,
|
|
Packit |
b099d7 |
char *index,
|
|
Packit |
b099d7 |
IDBRecordBufferPtr *buffer_return,
|
|
Packit |
b099d7 |
MrmCount *index_return)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* Local variables
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
Cardinal result ; /* function results */
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* Initialize search at the root of the index, then continue searching
|
|
Packit |
b099d7 |
* until either the index is found or search terminates at some leaf record.
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
if ( !file_id->index_root ) return MrmFAILURE ;
|
|
Packit |
b099d7 |
result = Idb__BM_GetRecord (file_id, file_id->index_root, buffer_return) ;
|
|
Packit |
b099d7 |
if ( result != MrmSUCCESS ) return result ;
|
|
Packit |
b099d7 |
if ( ! Idb__INX_ValidRecord(*buffer_return) )
|
|
Packit |
b099d7 |
return Urm__UT_Error ("Idb__INX_FindIndex", _MrmMMsg_0010,
|
|
Packit |
b099d7 |
file_id, NULL, MrmBAD_RECORD) ;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
do {
|
|
Packit |
b099d7 |
result =
|
|
Packit |
b099d7 |
Idb__INX_SearchIndex (file_id, index, *buffer_return, index_return) ;
|
|
Packit |
b099d7 |
if ( _IdbBufferRecordType(*buffer_return) == IDBrtIndexLeaf) return result ;
|
|
Packit |
b099d7 |
switch ( result )
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
case MrmINDEX_GT:
|
|
Packit |
b099d7 |
case MrmINDEX_LT:
|
|
Packit |
b099d7 |
result = Idb__INX_GetBtreeRecord
|
|
Packit |
b099d7 |
(file_id, buffer_return, *index_return, result) ;
|
|
Packit |
b099d7 |
if (result != MrmSUCCESS )
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
if (result == MrmNOT_FOUND)
|
|
Packit |
b099d7 |
result = MrmEOF;
|
|
Packit |
b099d7 |
return result ;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
break ;
|
|
Packit |
b099d7 |
default:
|
|
Packit |
b099d7 |
return result ;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
} while ( TRUE ) ;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
*++
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* PROCEDURE DESCRIPTION:
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* Idb__INX_SearchIndex searches a record for an index. The record
|
|
Packit |
b099d7 |
* may be either a leaf or a node record. If the index is found,
|
|
Packit |
b099d7 |
* index_return is its entry in the records index vector. If it is not
|
|
Packit |
b099d7 |
* found, then index_return locates the entry in the record at which
|
|
Packit |
b099d7 |
* search terminated.
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* Thus the interpretation of the return code is:
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* MrmSUCCESS found the index, and the index_return locates the entry
|
|
Packit |
b099d7 |
* MrmINDEX_GT index orders greater-than the entry at index_return
|
|
Packit |
b099d7 |
* MrmINDEX_LT index orders less-than the entry at index_return
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* FORMAL PARAMETERS:
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* file_id Open IDB file in which to find index
|
|
Packit |
b099d7 |
* index Case-sensitive index string
|
|
Packit |
b099d7 |
* buffer Buffer containing record to be searched
|
|
Packit |
b099d7 |
* index_return To return item's index in the records index vector
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* IMPLICIT INPUTS:
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* IMPLICIT OUTPUTS:
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* FUNCTION VALUE:
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* MrmSUCCESS operation succeeded
|
|
Packit |
b099d7 |
* MrmINDEX_GT index not found, but orders greater-than entry at
|
|
Packit |
b099d7 |
* index_return
|
|
Packit |
b099d7 |
* MrmINDEX_LT index not found, but orders less-than entry at
|
|
Packit |
b099d7 |
* index_return
|
|
Packit |
b099d7 |
* MrmFAILURE some other failure
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* SIDE EFFECTS:
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
*--
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
Cardinal
|
|
Packit |
b099d7 |
Idb__INX_SearchIndex (IDBFile file_id,
|
|
Packit |
b099d7 |
char *index,
|
|
Packit |
b099d7 |
IDBRecordBufferPtr buffer,
|
|
Packit |
b099d7 |
MrmCount *index_return)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* Local variables
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
MrmType buftyp ; /* buffer type */
|
|
Packit |
b099d7 |
IDBIndexLeafRecordPtr leafrec ; /* index leaf record */
|
|
Packit |
b099d7 |
IDBIndexLeafHdrPtr leafhdr ; /* index leaf header */
|
|
Packit |
b099d7 |
IDBIndexNodeRecordPtr noderec ; /* index node record */
|
|
Packit |
b099d7 |
IDBIndexNodeHdrPtr nodehdr ; /* index node header */
|
|
Packit |
b099d7 |
IDBIndexLeafEntryPtr leaf_ndxvec ; /* index leaf entry vector */
|
|
Packit |
b099d7 |
IDBIndexNodeEntryPtr node_ndxvec ; /* index node entry vector */
|
|
Packit |
b099d7 |
MrmCount ndxcnt ; /* number of entries in vector */
|
|
Packit |
b099d7 |
char *stgbase ; /* base adddress for string offsets */
|
|
Packit |
b099d7 |
int lowlim ; /* binary search lower limit index */
|
|
Packit |
b099d7 |
int uprlim ; /* binary search upper limit index */
|
|
Packit |
b099d7 |
char *ndxstg ; /* pointer to current index string */
|
|
Packit |
b099d7 |
int cmpres ; /* strncmp result */
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* Set up search pointers based on the record type
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
buftyp = _IdbBufferRecordType (buffer) ;
|
|
Packit |
b099d7 |
switch ( buftyp )
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
case IDBrtIndexLeaf:
|
|
Packit |
b099d7 |
leafrec = (IDBIndexLeafRecordPtr) buffer->IDB_record ;
|
|
Packit |
b099d7 |
leafhdr = (IDBIndexLeafHdrPtr) &leafrec->leaf_header ;
|
|
Packit |
b099d7 |
leaf_ndxvec = leafrec->index ;
|
|
Packit |
b099d7 |
ndxcnt = leafhdr->index_count ;
|
|
Packit |
b099d7 |
stgbase = (char *) leafrec->index ;
|
|
Packit |
b099d7 |
break ;
|
|
Packit |
b099d7 |
case IDBrtIndexNode:
|
|
Packit |
b099d7 |
noderec = (IDBIndexNodeRecordPtr) buffer->IDB_record ;
|
|
Packit |
b099d7 |
nodehdr = (IDBIndexNodeHdrPtr) &noderec->node_header ;
|
|
Packit |
b099d7 |
node_ndxvec = noderec->index ;
|
|
Packit |
b099d7 |
ndxcnt = nodehdr->index_count ;
|
|
Packit |
b099d7 |
stgbase = (char *) noderec->index ;
|
|
Packit |
b099d7 |
break ;
|
|
Packit |
b099d7 |
default:
|
|
Packit |
b099d7 |
return Urm__UT_Error ("Idb__INX_SearchIndex", _MrmMMsg_0010,
|
|
Packit |
b099d7 |
file_id, NULL, MrmBAD_RECORD) ;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* Search the index vector for the given index (binary search)
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
Idb__BM_MarkActivity (buffer) ;
|
|
Packit |
b099d7 |
for ( lowlim=0,uprlim=ndxcnt-1 ; lowlim<=uprlim ; )
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
*index_return = (lowlim+uprlim) / 2 ;
|
|
Packit |
b099d7 |
ndxstg = (buftyp==IDBrtIndexLeaf) ?
|
|
Packit |
b099d7 |
(char *) stgbase + leaf_ndxvec[*index_return].index_stg :
|
|
Packit |
b099d7 |
(char *) stgbase + node_ndxvec[*index_return].index_stg ;
|
|
Packit |
b099d7 |
cmpres = strncmp (index, ndxstg, IDBMaxIndexLength) ;
|
|
Packit |
b099d7 |
if ( cmpres == 0 ) return MrmSUCCESS ;
|
|
Packit |
b099d7 |
if ( cmpres < 0 ) uprlim = *index_return - 1 ;
|
|
Packit |
b099d7 |
if ( cmpres > 0 ) lowlim = *index_return + 1 ;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* Not found, result determined by final ordering.
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
return (cmpres>0) ? MrmINDEX_GT : MrmINDEX_LT ;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
*++
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* PROCEDURE DESCRIPTION:
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* This routine reads in the next level index record in the B-tree
|
|
Packit |
b099d7 |
* associated with some entry in the current record (i.e. the one
|
|
Packit |
b099d7 |
* currently contained in the buffer). The buffer pointer is reset.
|
|
Packit |
b099d7 |
* The order variable indicates which record to read:
|
|
Packit |
b099d7 |
* MrmINDEX_GT - read the record ordering greater-than the entry
|
|
Packit |
b099d7 |
* MrmINDEX_LT - read the record ordering less-than the entry
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* FORMAL PARAMETERS:
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* file_id Open IDB file from which to read record
|
|
Packit |
b099d7 |
* buffer_return points to current buffer; reset to buffer read in
|
|
Packit |
b099d7 |
* entry_index entry in current buffer to use as reference
|
|
Packit |
b099d7 |
* order MrmINDEX_GT for GT ordered record, else MrmINDEX_LT
|
|
Packit |
b099d7 |
* for LT ordered record.
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* IMPLICIT INPUTS:
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* IMPLICIT OUTPUTS:
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* FUNCTION VALUE:
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* MrmSUCCESS operation succeeded
|
|
Packit |
b099d7 |
* MrmBAD_ORDER Order variable has illegal value
|
|
Packit |
b099d7 |
* MrmBAD_RECORD new record not an index record
|
|
Packit |
b099d7 |
* MrmFAILURE some other failure
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* SIDE EFFECTS:
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
*--
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
Cardinal
|
|
Packit |
b099d7 |
Idb__INX_GetBtreeRecord ( IDBFile file_id,
|
|
Packit |
b099d7 |
IDBRecordBufferPtr *buffer_return,
|
|
Packit |
b099d7 |
MrmCount entry_index,
|
|
Packit |
b099d7 |
Cardinal order)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* Local variables
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
Cardinal result ; /* function results */
|
|
Packit |
b099d7 |
IDBIndexNodeRecordPtr recptr ; /* node record in buffer */
|
|
Packit |
b099d7 |
IDBRecordNumber recno ; /* Record number to read in */
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* Set buffer pointers
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
recptr = (IDBIndexNodeRecordPtr) (*buffer_return)->IDB_record ;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* Retrieve the record number
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
switch ( order )
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
case MrmINDEX_GT:
|
|
Packit |
b099d7 |
recno = recptr->index[entry_index].GT_record ;
|
|
Packit |
b099d7 |
break ;
|
|
Packit |
b099d7 |
case MrmINDEX_LT:
|
|
Packit |
b099d7 |
recno = recptr->index[entry_index].LT_record ;
|
|
Packit |
b099d7 |
break ;
|
|
Packit |
b099d7 |
default:
|
|
Packit |
b099d7 |
return Urm__UT_Error ("Idb__INX_GetBTreeRecord", _MrmMMsg_0010,
|
|
Packit |
b099d7 |
file_id, NULL, MrmBAD_ORDER) ;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* Retrieve and sanity check the record
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
result = Idb__BM_GetRecord (file_id, recno, buffer_return) ;
|
|
Packit |
b099d7 |
if ( result != MrmSUCCESS ) return result ;
|
|
Packit |
b099d7 |
if ( ! Idb__INX_ValidRecord(*buffer_return) )
|
|
Packit |
b099d7 |
return Urm__UT_Error ("Idb__INX_GetBTreeRecord", _MrmMMsg_0010,
|
|
Packit |
b099d7 |
file_id, NULL, MrmBAD_RECORD) ;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* Record successfully retrieved
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
return MrmSUCCESS ;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
*++
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* PROCEDURE DESCRIPTION:
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* This is the internal routine which searches the database for
|
|
Packit |
b099d7 |
* indexed resources matching a filter. It starts at the current node,
|
|
Packit |
b099d7 |
* then recurses down the BTree inspecting every entry. Each entry
|
|
Packit |
b099d7 |
* which matches the filter is appended to the index list.
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* FORMAL PARAMETERS:
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* file_id The IDB file id returned by XmIdbOpenFile
|
|
Packit |
b099d7 |
* recno The record to be searched. If a node entry,
|
|
Packit |
b099d7 |
* then each pointed-to record is also searched.
|
|
Packit |
b099d7 |
* group_filter if not null, entries found must match this group
|
|
Packit |
b099d7 |
* type_filter if not null, entries found must match this type
|
|
Packit |
b099d7 |
* index_list A pointer list in which to return index
|
|
Packit |
b099d7 |
* strings for matches. The required strings
|
|
Packit |
b099d7 |
* are automatically allocated.
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* IMPLICIT INPUTS:
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* IMPLICIT OUTPUTS:
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* FUNCTION VALUE:
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* MrmSUCCESS operation succeeded
|
|
Packit |
b099d7 |
* MrmFAILURE operation failed, no further reason
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* SIDE EFFECTS:
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
*--
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
Cardinal
|
|
Packit |
b099d7 |
Idb__INX_FindResources (IDBFile file_id,
|
|
Packit |
b099d7 |
IDBRecordNumber recno,
|
|
Packit |
b099d7 |
MrmGroup group_filter,
|
|
Packit |
b099d7 |
MrmType type_filter,
|
|
Packit |
b099d7 |
URMPointerListPtr index_list)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* Local variables
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
Cardinal result ; /* function results */
|
|
Packit |
b099d7 |
IDBRecordBufferPtr bufptr ; /* buffer containing entry */
|
|
Packit |
b099d7 |
int entndx ; /* entry loop index */
|
|
Packit |
b099d7 |
IDBIndexLeafRecordPtr leafrec ; /* index leaf record */
|
|
Packit |
b099d7 |
IDBIndexLeafHdrPtr leafhdr ; /* index leaf header */
|
|
Packit |
b099d7 |
IDBIndexNodeRecordPtr noderec ; /* index node record */
|
|
Packit |
b099d7 |
IDBIndexNodeHdrPtr nodehdr ; /* index node header */
|
|
Packit |
b099d7 |
IDBIndexLeafEntryPtr leaf_ndxvec ; /* index leaf entry vector */
|
|
Packit |
b099d7 |
IDBIndexNodeEntryPtr node_ndxvec ; /* index node entry vector */
|
|
Packit |
b099d7 |
MrmCount ndxcnt ; /* number of entries in vector */
|
|
Packit |
b099d7 |
char *stgbase ; /* base adddress for string offsets */
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* Read the record in, then bind pointers and process the record.
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
result = Idb__BM_GetRecord (file_id, recno, &bufptr) ;
|
|
Packit |
b099d7 |
if ( result != MrmSUCCESS ) return result ;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
switch ( _IdbBufferRecordType (bufptr) )
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* Simply apply the filter to all entries in the leaf record
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
case IDBrtIndexLeaf:
|
|
Packit |
b099d7 |
leafrec = (IDBIndexLeafRecordPtr) bufptr->IDB_record ;
|
|
Packit |
b099d7 |
leafhdr = (IDBIndexLeafHdrPtr) &leafrec->leaf_header ;
|
|
Packit |
b099d7 |
leaf_ndxvec = leafrec->index ;
|
|
Packit |
b099d7 |
ndxcnt = leafhdr->index_count ;
|
|
Packit |
b099d7 |
stgbase = (char *) leafrec->index ;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
for ( entndx=0 ; entndx
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
IDBDataHandle entry_data;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
entry_data.rec_no = leaf_ndxvec[entndx].data.internal_id.rec_no;
|
|
Packit |
b099d7 |
entry_data.item_offs =
|
|
Packit |
b099d7 |
leaf_ndxvec[entndx].data.internal_id.item_offs;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if ( Idb__DB_MatchFilter(file_id, entry_data, group_filter,
|
|
Packit |
b099d7 |
type_filter) )
|
|
Packit |
b099d7 |
UrmPlistAppendString (index_list,
|
|
Packit |
b099d7 |
stgbase+leaf_ndxvec[entndx].index_stg) ;
|
|
Packit |
b099d7 |
Idb__BM_MarkActivity (bufptr) ;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
return MrmSUCCESS ;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* Process the first LT record, then process each index followed by
|
|
Packit |
b099d7 |
* its GT record. This will produce a correctly ordered list. The
|
|
Packit |
b099d7 |
* record is read again, and all pointers bound, after each FindResources
|
|
Packit |
b099d7 |
* call in order to guarantee that buffer turning has not purged the
|
|
Packit |
b099d7 |
* current record from memory
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
case IDBrtIndexNode:
|
|
Packit |
b099d7 |
noderec = (IDBIndexNodeRecordPtr) bufptr->IDB_record ;
|
|
Packit |
b099d7 |
nodehdr = (IDBIndexNodeHdrPtr) &noderec->node_header ;
|
|
Packit |
b099d7 |
node_ndxvec = noderec->index ;
|
|
Packit |
b099d7 |
ndxcnt = nodehdr->index_count ;
|
|
Packit |
b099d7 |
stgbase = (char *) noderec->index ;
|
|
Packit |
b099d7 |
result = Idb__INX_FindResources
|
|
Packit |
b099d7 |
(file_id, node_ndxvec[0].LT_record,
|
|
Packit |
b099d7 |
group_filter, type_filter, index_list) ;
|
|
Packit |
b099d7 |
if ( result != MrmSUCCESS ) return result ;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
for ( entndx=0 ; entndx
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
IDBDataHandle entry_data;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
entry_data.rec_no = node_ndxvec[entndx].data.internal_id.rec_no;
|
|
Packit |
b099d7 |
entry_data.item_offs =
|
|
Packit |
b099d7 |
node_ndxvec[entndx].data.internal_id.item_offs;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
Idb__BM_GetRecord (file_id, recno, &bufptr) ;
|
|
Packit |
b099d7 |
noderec = (IDBIndexNodeRecordPtr) bufptr->IDB_record ;
|
|
Packit |
b099d7 |
nodehdr = (IDBIndexNodeHdrPtr) &noderec->node_header ;
|
|
Packit |
b099d7 |
node_ndxvec = noderec->index ;
|
|
Packit |
b099d7 |
stgbase = (char *) noderec->index ;
|
|
Packit |
b099d7 |
if ( Idb__DB_MatchFilter
|
|
Packit |
b099d7 |
(file_id, entry_data, group_filter, type_filter) )
|
|
Packit |
b099d7 |
UrmPlistAppendString (index_list,
|
|
Packit |
b099d7 |
stgbase+node_ndxvec[entndx].index_stg) ;
|
|
Packit |
b099d7 |
result = Idb__INX_FindResources
|
|
Packit |
b099d7 |
(file_id, node_ndxvec[entndx].GT_record,
|
|
Packit |
b099d7 |
group_filter, type_filter, index_list) ;
|
|
Packit |
b099d7 |
if ( result != MrmSUCCESS ) return result ;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
return MrmSUCCESS ;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
default:
|
|
Packit |
b099d7 |
return Urm__UT_Error ("Idb__INX_FindResources", _MrmMMsg_0010,
|
|
Packit |
b099d7 |
file_id, NULL, MrmBAD_RECORD) ;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|