Blame lib/Mrm/MrmIindex.c

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