Blame lib/Mrm/MrmIbuffer.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
 
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: MrmIbuffer.c /main/16 1996/11/13 13:55:44 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
 *  FACILITY:
Packit b099d7
 *
Packit b099d7
 *      UIL Resource Manager (URM): IDB Facility
Packit b099d7
 *	Buffer management routines
Packit b099d7
 *
Packit b099d7
 *  ABSTRACT:
Packit b099d7
 *
Packit b099d7
 *	These routines manage the buffer pool for all IDB files, and manage
Packit b099d7
 *	reading and writing actual file records into these buffers on request.
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
 *  TABLE OF CONTENTS
Packit b099d7
 *
Packit b099d7
 *	Idb__BM_InitBufferVector	- Allocates and initializes
Packit b099d7
 *					  the buffer vector 
Packit b099d7
 *
Packit b099d7
 *	Idb__BM_GetBuffer		- Acquire a free buffer
Packit b099d7
 *
Packit b099d7
 *	Idb__BM_MarkActivity		- Mark a buffer as having seen activity
Packit b099d7
 *
Packit b099d7
 *	Idb__BM_MarkModified		- Mark a buffer as modified for write
Packit b099d7
 *
Packit b099d7
 *	Idb__BM_GetRecord		- Get a record into some buffer
Packit b099d7
 *
Packit b099d7
 *	Idb__BM_InitRecord		- Initialize a new record into
Packit b099d7
 *					  some buffer
Packit b099d7
 *
Packit b099d7
 *	Idb__BM_InitDataRecord		- Initialize a new data record into
Packit b099d7
 *					  some buffer
Packit b099d7
 *
Packit b099d7
 *	Idb__BM_Decommit		- Through with buffer contents
Packit b099d7
 *
Packit b099d7
 *	Idb__BM_DecommitAll		- Decommit all buffers for some file
Packit b099d7
 */
Packit b099d7

Packit b099d7
/*
Packit b099d7
 *
Packit b099d7
 *  OWN VARIABLE DECLARATIONS
Packit b099d7
 *
Packit b099d7
 */
Packit b099d7
Packit b099d7
/*
Packit b099d7
 * This module manages a pool of buffers for all open IDB files. The pool
Packit b099d7
 * is located and managed via the following globals.
Packit b099d7
 */
Packit b099d7
Packit b099d7
/*
Packit b099d7
 * The following defines the number of buffers in the buffer pool. Once
Packit b099d7
 * the pool is initialized, this number is invariant (currently). This
Packit b099d7
 * variable will be accessible via currently undefined means for applications
Packit b099d7
 * to tailor the buffer pool size at startup.
Packit b099d7
 */
Packit b099d7
externaldef(idb__buffer_pool_size)	int	idb__buffer_pool_size = 8 ;
Packit b099d7
Packit b099d7
Packit b099d7
/*
Packit b099d7
 * The following pointer locates a vector of pointers to buffers. This pointer
Packit b099d7
 * is initially NULL. The first request for a buffer detects that the buffer
Packit b099d7
 * has not been allocated, and does the following:
Packit b099d7
 *	o Allocate a vector of buffer pointers (IDBRecordBufferPtr) containing
Packit b099d7
 *	  the number of entries specified in idb__buffer_pool_size.
Packit b099d7
 *
Packit b099d7
 * Thereafter, this vector locates the buffer pool.
Packit b099d7
 */
Packit b099d7
static	IDBRecordBufferPtr	idb__buffer_pool_vec = NULL ;
Packit b099d7
Packit b099d7
Packit b099d7
/*
Packit b099d7
 * The following counter is used to maintain the activity count in all
Packit b099d7
 * buffers.
Packit b099d7
 */
Packit b099d7
static	long int		idb__buffer_activity_count = 1 ;
Packit b099d7
Packit b099d7
Packit b099d7

Packit b099d7
/*
Packit b099d7
 *++
Packit b099d7
 *
Packit b099d7
 *  PROCEDURE DESCRIPTION:
Packit b099d7
 *
Packit b099d7
 *	Idb__BM_InitBufferVector is responsible for initializaing
Packit b099d7
 *	the buffer pool. This routine allocates the vector of record
Packit b099d7
 *	buffers, but does not allocate the actual buffer for each
Packit b099d7
 *	record, which is done on demand.
Packit b099d7
 *
Packit b099d7
 *  FORMAL PARAMETERS:
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__BM_InitBufferVector (void)
Packit b099d7
{
Packit b099d7
Packit b099d7
  /*
Packit b099d7
   *  Local variables
Packit b099d7
   */
Packit b099d7
  Cardinal		ndx ;		/* loop variable */
Packit b099d7
  IDBRecordBufferPtr	bufptr ;	/* entry into buffer pool vector */
Packit b099d7
Packit b099d7
  idb__buffer_pool_vec = (IDBRecordBufferPtr) XtMalloc
Packit b099d7
    (idb__buffer_pool_size*sizeof(IDBRecordBuffer)) ;
Packit b099d7
  if ( idb__buffer_pool_vec == NULL )
Packit b099d7
    return Urm__UT_Error ("Idb__BM_InitBufferVector", _MrmMMsg_0000,
Packit b099d7
			  NULL, NULL, MrmFAILURE) ;
Packit b099d7
Packit b099d7
  for ( ndx=0,bufptr=idb__buffer_pool_vec ;
Packit b099d7
        ndx
Packit b099d7
        ndx++,bufptr++ )
Packit b099d7
    {
Packit b099d7
      bufptr->validation = IDBRecordBufferValid;
Packit b099d7
      bufptr->activity = 0 ;
Packit b099d7
      bufptr->access = 0 ;
Packit b099d7
      bufptr->cur_file = NULL ;
Packit b099d7
      bufptr->modified = FALSE ;
Packit b099d7
      bufptr->IDB_record = NULL ;
Packit b099d7
    }
Packit b099d7
Packit b099d7
  return MrmSUCCESS;
Packit b099d7
Packit b099d7
}
Packit b099d7
Packit b099d7

Packit b099d7
/*
Packit b099d7
 *++
Packit b099d7
 *
Packit b099d7
 *  PROCEDURE DESCRIPTION:
Packit b099d7
 *
Packit b099d7
 *	Idb__BM_GetBuffer acquires a buffer from the buffer pool. The
Packit b099d7
 *	buffer chosen is some buffer with the lowest activity count. If
Packit b099d7
 *	necessary, its contents are written to disk. Note that a buffer
Packit b099d7
 *	which has been decommitted (activity count = 0) may be used
Packit b099d7
 *	immediately - a search for a buffer with a lower activity count
Packit b099d7
 *	is not required.
Packit b099d7
 *
Packit b099d7
 *	This routine is responsible for initializaing the buffer pool if
Packit b099d7
 *	it is not initialized. It is also responsible for acquiring
Packit b099d7
 *	a record buffer if a buffer pool vector entry is needed but has none.
Packit b099d7
 *
Packit b099d7
 *  FORMAL PARAMETERS:
Packit b099d7
 *
Packit b099d7
 *	file_id		Open IDB file
Packit b099d7
 *	buffer_return	Returns a free buffer, contents undefined
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__BM_GetBuffer (IDBFile			file_id,
Packit b099d7
		   IDBRecordBufferPtr		*buffer_return)
Packit b099d7
{
Packit b099d7
Packit b099d7
  /*
Packit b099d7
   * Local macro to complete allocation of a buffer to a file, and
Packit b099d7
   * mark its activity.
Packit b099d7
   */
Packit b099d7
#define _IDB_Getbuffer_return() 					\
Packit b099d7
  {									\
Packit b099d7
    (*buffer_return)->cur_file = file_id;				\
Packit b099d7
    (*buffer_return)->access = file_id->access;				\
Packit b099d7
    Idb__BM_MarkActivity (*buffer_return);				\
Packit b099d7
    return MrmSUCCESS;							\
Packit b099d7
  }
Packit b099d7
Packit b099d7
  /*
Packit b099d7
   *  Local variables
Packit b099d7
   */
Packit b099d7
  Cardinal		result ;	/* function results */
Packit b099d7
  int			ndx ;		/* loop index */
Packit b099d7
  long int		lowest ;	/* lowest activity count found */
Packit b099d7
  IDBRecordBufferPtr	curbuf ;	/* current buffer being examined */
Packit b099d7
Packit b099d7
  /*
Packit b099d7
   * If the buffer pool is uninitialized, allocate it and
Packit b099d7
   * return the first buffer in the pool. Else search the buffer pool for the
Packit b099d7
   * buffer with the lowest activity. Decommited/0 activity buffers can
Packit b099d7
   * be returned immediately.
Packit b099d7
   */
Packit b099d7
  if (idb__buffer_pool_vec == NULL)
Packit b099d7
    {
Packit b099d7
      result = Idb__BM_InitBufferVector () ;
Packit b099d7
      if ( result != MrmSUCCESS ) return result ;
Packit b099d7
      *buffer_return = idb__buffer_pool_vec ;
Packit b099d7
    }
Packit b099d7
  else
Packit b099d7
    {
Packit b099d7
      lowest = idb__buffer_activity_count;
Packit b099d7
      for ( ndx=0,curbuf=idb__buffer_pool_vec ;
Packit b099d7
	    ndx
Packit b099d7
	    ndx++,curbuf++ )
Packit b099d7
        {
Packit b099d7
	  if ( curbuf->activity == 0 )
Packit b099d7
            {
Packit b099d7
	      *buffer_return = curbuf ;
Packit b099d7
	      break ;
Packit b099d7
            }
Packit b099d7
	  if ( curbuf->activity < lowest )
Packit b099d7
            {
Packit b099d7
	      *buffer_return = curbuf ;
Packit b099d7
	      lowest = curbuf->activity ;
Packit b099d7
            }
Packit b099d7
        }
Packit b099d7
    }
Packit b099d7
Packit b099d7
  /*
Packit b099d7
   * Allocate a record buffer if required, and return immediately if
Packit b099d7
   * the buffer is decommitted or not yet used.
Packit b099d7
   */
Packit b099d7
  if ( (*buffer_return)->IDB_record == NULL )
Packit b099d7
    {
Packit b099d7
      (*buffer_return)->IDB_record =
Packit b099d7
        (IDBDummyRecord *) XtMalloc(sizeof(IDBDummyRecord)) ;
Packit b099d7
      if ( (*buffer_return)->IDB_record == NULL )
Packit b099d7
        return Urm__UT_Error ("Idb__BM_GetBuffer",
Packit b099d7
			      _MrmMMsg_0001, NULL, NULL, MrmFAILURE) ;
Packit b099d7
      _IDB_Getbuffer_return ();
Packit b099d7
    }
Packit b099d7
  if ( (*buffer_return)->activity == 0 ) _IDB_Getbuffer_return ();
Packit b099d7
Packit b099d7
  /*
Packit b099d7
   * We have set the buffer pointer. See if it needs to be updated on
Packit b099d7
   * disk, and do so if required.
Packit b099d7
   */
Packit b099d7
  if ( ((*buffer_return)->access == URMWriteAccess) &&
Packit b099d7
       ((*buffer_return)->modified) )
Packit b099d7
    {
Packit b099d7
      result = Idb__BM_Decommit (*buffer_return) ;
Packit b099d7
      if ( result != MrmSUCCESS ) return result ;
Packit b099d7
    }
Packit b099d7
Packit b099d7
  /*
Packit b099d7
   * Allocate the buffer to the file, and return.
Packit b099d7
   */
Packit b099d7
  _IDB_Getbuffer_return ();
Packit b099d7
Packit b099d7
}
Packit b099d7
Packit b099d7

Packit b099d7
/*
Packit b099d7
 *++
Packit b099d7
 *
Packit b099d7
 *  PROCEDURE DESCRIPTION:
Packit b099d7
 *
Packit b099d7
 *	Idb__BM_MarkActivity asserts that the buffer has seen some activity,
Packit b099d7
 *	and updates its activity count. This is done by storing the current
Packit b099d7
 *	idb__buffer_activity_count++ in the buffer.
Packit b099d7
 *
Packit b099d7
 *  FORMAL PARAMETERS:
Packit b099d7
 *
Packit b099d7
 *	buffer		Record buffer to mark as modified
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__BM_MarkActivity (IDBRecordBufferPtr	buffer)
Packit b099d7
{
Packit b099d7
Packit b099d7
  if ( ! Idb__BM_Valid(buffer) )
Packit b099d7
    return Urm__UT_Error ("Idb__BM_MarkActivity", _MrmMMsg_0002,
Packit b099d7
			  NULL, NULL, MrmNOT_VALID) ;
Packit b099d7
  buffer->activity = idb__buffer_activity_count++ ;
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
 *	Idb__BM_MarkModified asserts that the buffer has been modified,
Packit b099d7
 *	and sets its modify flag. Its activity count is updated.
Packit b099d7
 *
Packit b099d7
 *  FORMAL PARAMETERS:
Packit b099d7
 *
Packit b099d7
 *	buffer		Record buffer to mark as modified
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__BM_MarkModified (IDBRecordBufferPtr	buffer)
Packit b099d7
Packit b099d7
{
Packit b099d7
Packit b099d7
  if ( ! Idb__BM_Valid(buffer) )
Packit b099d7
    return Urm__UT_Error ("Idb__BM_MarkModified", _MrmMMsg_0002,
Packit b099d7
			  NULL, NULL, MrmNOT_VALID) ;
Packit b099d7
  buffer->activity = idb__buffer_activity_count++ ;
Packit b099d7
  buffer->modified = TRUE ;
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
 *	Idb__BM_GetRecord reads a record from an open IDB file into a buffer.
Packit b099d7
 *	If the record is already available in some buffer, then that buffer is
Packit b099d7
 *	returned without re-reading the record from disk. Otherwise, a buffer is
Packit b099d7
 *	acquired, the record read into it, and the buffer is returned. The
Packit b099d7
 *	buffer's activity count is updated.
Packit b099d7
 *
Packit b099d7
 *  FORMAL PARAMETERS:
Packit b099d7
 *
Packit b099d7
 *	file_id		Open IDB file
Packit b099d7
 *	record		The desired record number
Packit b099d7
 *	buffer_return	Returns buffer containing 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
 *	MrmNOT_FOUND	record doesn't exist
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__BM_GetRecord (IDBFile                     file_id,
Packit b099d7
		   IDBRecordNumber             record,
Packit b099d7
		   IDBRecordBufferPtr          *buffer_return)
Packit b099d7
{
Packit b099d7
Packit b099d7
  /*
Packit b099d7
   *  Local variables
Packit b099d7
   */
Packit b099d7
  Cardinal		result ;  /* function results */
Packit b099d7
  int			ndx ;	  /* loop index */
Packit b099d7
  IDBRecordBufferPtr	curbuf ;  /* current buffer being examined */
Packit b099d7
  unsigned char		*buf_src; /* tmp pointer to location in uid buffer */
Packit b099d7
Packit b099d7
  /*
Packit b099d7
   * If buffer pool is unallocated, get a buffer (which WILL allocate it),
Packit b099d7
   * and read the record into that. Else see if the record is already in
Packit b099d7
   * memory, and return it if so. If the record is not found, get a buffer
Packit b099d7
   * to read it into. We exit this if statement with a buffer ready for
Packit b099d7
   * the read operation.
Packit b099d7
   */
Packit b099d7
  if ( idb__buffer_pool_vec == NULL )
Packit b099d7
    {
Packit b099d7
      result = Idb__BM_GetBuffer (file_id, buffer_return) ;
Packit b099d7
      if ( result != MrmSUCCESS ) return result ;
Packit b099d7
    }
Packit b099d7
  else
Packit b099d7
    {
Packit b099d7
      for ( ndx=0,curbuf=idb__buffer_pool_vec ;
Packit b099d7
            ndx
Packit b099d7
            ndx++,curbuf++ )
Packit b099d7
        {
Packit b099d7
	  if ( (curbuf->cur_file==file_id) &&
Packit b099d7
	       (curbuf->IDB_record->header.record_num==record) )
Packit b099d7
            {
Packit b099d7
	      *buffer_return = curbuf ;
Packit b099d7
	      Idb__BM_MarkActivity (*buffer_return) ;
Packit b099d7
	      return MrmSUCCESS ;
Packit b099d7
            }
Packit b099d7
        }
Packit b099d7
      result = Idb__BM_GetBuffer (file_id, buffer_return) ;
Packit b099d7
      if ( result != MrmSUCCESS ) return result ;
Packit b099d7
    }
Packit b099d7
Packit b099d7
  /*
Packit b099d7
   * Read the record into the buffer.
Packit b099d7
   */
Packit b099d7
  if ( file_id->in_memory ) {
Packit b099d7
    buf_src = file_id->uid_buffer + (record-1)*IDBRecordSize;
Packit b099d7
    UrmBCopy(buf_src, (*buffer_return)->IDB_record, IDBRecordSize);
Packit b099d7
    result = MrmSUCCESS;
Packit b099d7
  }
Packit b099d7
  else
Packit b099d7
    result = Idb__FU_GetBlock(file_id->lowlevel_id, record, 
Packit b099d7
			      (char*)(*buffer_return)->IDB_record) ;
Packit b099d7
Packit b099d7
Packit b099d7
  if ( result != MrmSUCCESS )
Packit b099d7
    return Urm__UT_Error ("Idb__BM_GetRecord", _MrmMMsg_0003,
Packit b099d7
			  file_id, NULL, result) ;
Packit b099d7
  file_id->get_count++ ;
Packit b099d7
Packit b099d7
  /*
Packit b099d7
   * Validate the record, this is the first routine that is called to read
Packit b099d7
   * from a newly opened file.  If the byte order is different, we find it
Packit b099d7
   * here.  
Packit b099d7
   */
Packit b099d7
Packit b099d7
Packit b099d7
  if ( (*buffer_return)->IDB_record->header.validation != 
Packit b099d7
       IDBRecordHeaderValid ) {
Packit b099d7
    swapbytes( (*buffer_return)->IDB_record->header.validation );
Packit b099d7
    if ((*buffer_return)->IDB_record->header.validation == IDBRecordHeaderValid)
Packit b099d7
      {
Packit b099d7
	/* must be a file needing byte swapping */
Packit b099d7
	file_id->byte_swapped = TRUE;
Packit b099d7
	Idb__BM_SwapRecordBytes (*buffer_return);
Packit b099d7
	Idb__BM_MarkActivity (*buffer_return);
Packit b099d7
	return MrmSUCCESS ;
Packit b099d7
      }
Packit b099d7
    /* byte swapping has done no good, return error */
Packit b099d7
    return Urm__UT_Error("Idb__BM_GetRecord", _MrmMMsg_0005,
Packit b099d7
			 file_id, NULL, MrmNOT_VALID) ;
Packit b099d7
  }
Packit b099d7
Packit b099d7
  /*
Packit b099d7
   * Record successfully read
Packit b099d7
   */
Packit b099d7
  Idb__BM_MarkActivity (*buffer_return) ;
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
 *	Idb__BM_InitRecord initializes a new record for the file. A buffer
Packit b099d7
 *	is acquired, and the record number and record type set. The record
Packit b099d7
 *	number may be specified; if the record number given is <= 0, then the
Packit b099d7
 *	next available record is taken from the file header. The next
Packit b099d7
 *	available record number is updated to the new record number if it is
Packit b099d7
 *	greater than the current value. The record is marked for write access,
Packit b099d7
 *	and as modified. It is not written to disk. The buffer's activity
Packit b099d7
 *	count is updated.
Packit b099d7
 *
Packit b099d7
 *  FORMAL PARAMETERS:
Packit b099d7
 *
Packit b099d7
 *	file_id		Open IDB file
Packit b099d7
 *	record		The desired record number. This will be a new record in
Packit b099d7
 *			the file
Packit b099d7
 *	type		The record type, from IDBrt...
Packit b099d7
 *	buffer_return	Returns buffer initialized for record, with type set.
Packit b099d7
 *			Access is URMWriteAccess, modified.
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__BM_InitRecord (IDBFile                     file_id,
Packit b099d7
		    IDBRecordNumber             record,
Packit b099d7
		    MrmType                     type,
Packit b099d7
		    IDBRecordBufferPtr          *buffer_return)
Packit b099d7
{
Packit b099d7
Packit b099d7
Packit b099d7
  if ((Idb__BM_GetBuffer (file_id, buffer_return)) != MrmSUCCESS)
Packit b099d7
    return MrmFAILURE;
Packit b099d7
Packit b099d7
  /*
Packit b099d7
   * Set the record number if required. Since the last_record parameter
Packit b099d7
   * records the last record currently in use, it must be incremented
Packit b099d7
   * before use to give the new last record.
Packit b099d7
   */
Packit b099d7
  if (record <= 0)
Packit b099d7
    record = ++file_id->last_record;
Packit b099d7
Packit b099d7
  if (record > file_id->last_record)
Packit b099d7
    file_id->last_record = record;
Packit b099d7
Packit b099d7
  (*buffer_return)->IDB_record->header.validation = IDBRecordHeaderValid ;
Packit b099d7
  (*buffer_return)->IDB_record->header.record_num = record ;
Packit b099d7
  (*buffer_return)->IDB_record->header.record_type = type ;
Packit b099d7
Packit b099d7
  (*buffer_return)->access	= file_id->access ;
Packit b099d7
  (*buffer_return)->cur_file	= file_id ;
Packit b099d7
  (*buffer_return)->modified	= TRUE ;
Packit b099d7
Packit b099d7
  Idb__BM_MarkActivity (*buffer_return) ;
Packit b099d7
Packit b099d7
  /*
Packit b099d7
   * Update the record type counter in the file header
Packit b099d7
   */
Packit b099d7
  file_id->rt_counts[type]++ ;
Packit b099d7
Packit b099d7
  /*
Packit b099d7
   * Successfully initialized
Packit b099d7
   */
Packit b099d7
  return MrmSUCCESS ;
Packit b099d7
Packit b099d7
}
Packit b099d7
Packit b099d7

Packit b099d7
/*
Packit b099d7
 *++
Packit b099d7
 *
Packit b099d7
 *  PROCEDURE DESCRIPTION:
Packit b099d7
 *
Packit b099d7
 *	Idb__BM_InitDataRecord initializes a new data record for the file.
Packit b099d7
 *	A buffer is acquired, and the record number and record type set. 
Packit b099d7
 *	The record number may be specified; if the record number given
Packit b099d7
 *	is <= 0, then the next available record is taken from the file
Packit b099d7
 *	header.  The next available record number is updated to the
Packit b099d7
 *	new record number if it is greater than the current value.  The
Packit b099d7
 *	record is marked for write access, and as modified.  It is not
Packit b099d7
 *	written to disk. The buffer's activity count is updated.  This
Packit b099d7
 *	routine is nearly identical to InitRecord. 
Packit b099d7
 *
Packit b099d7
 *  FORMAL PARAMETERS:
Packit b099d7
 *
Packit b099d7
 *	file_id		Open IDB file
Packit b099d7
 *	buffer_return	Returns buffer initialized for record, with type set.
Packit b099d7
 *			Access is URMWriteAccess, modified.
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__BM_InitDataRecord (IDBFile			file_id,
Packit b099d7
			IDBRecordBufferPtr	*buffer_return)
Packit b099d7
{
Packit b099d7
Packit b099d7
  /*
Packit b099d7
   *  Local variables
Packit b099d7
   */
Packit b099d7
  Cardinal		result ;	/* function results */
Packit b099d7
  IDBDataRecordPtr	data_rec;	/* data record specific */
Packit b099d7
Packit b099d7
Packit b099d7
  /*
Packit b099d7
   * Get a new record
Packit b099d7
   */
Packit b099d7
  result = Idb__BM_InitRecord (file_id, 0, IDBrtData, buffer_return) ;
Packit b099d7
  if ( result != MrmSUCCESS ) return result ;
Packit b099d7
Packit b099d7
  /*
Packit b099d7
   * Set the last data record pointer in the file
Packit b099d7
   */
Packit b099d7
  file_id->last_data_record = _IdbBufferRecordNumber (*buffer_return) ;
Packit b099d7
Packit b099d7
  /*
Packit b099d7
   * Initialize the record contents
Packit b099d7
   */
Packit b099d7
  data_rec = (IDBDataRecord *) (*buffer_return)->IDB_record;
Packit b099d7
Packit b099d7
  data_rec->data_header.free_ptr	= 0 ;
Packit b099d7
  data_rec->data_header.free_count	= IDBDataFreeMax ;
Packit b099d7
  data_rec->data_header.num_entry	= 0 ;
Packit b099d7
  data_rec->data_header.last_entry	= 0 ;
Packit b099d7
  Idb__BM_MarkActivity (*buffer_return) ;
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
 *	Idb__BM_Decommit asserts that the buffer contents are no longer
Packit b099d7
 *	required to be in memory. If the buffer is marked for write access
Packit b099d7
 *	and as modified, it is written to disk. Then the modified flag is
Packit b099d7
 *	reset and the activity count set to 0 (least value).
Packit b099d7
 *
Packit b099d7
 *	Note that GetRecord may legally re-acquire a decommitted buffer.
Packit b099d7
 *
Packit b099d7
 *  FORMAL PARAMETERS:
Packit b099d7
 *
Packit b099d7
 *	buffer		Record buffer to decommit
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__BM_Decommit (IDBRecordBufferPtr		buffer)
Packit b099d7
{
Packit b099d7
Packit b099d7
  /*
Packit b099d7
   *  Local variables
Packit b099d7
   */
Packit b099d7
  Cardinal		result ;	/* function results */
Packit b099d7
Packit b099d7
Packit b099d7
  if ( ! Idb__BM_Valid(buffer) )
Packit b099d7
    return Urm__UT_Error ("Idb__BM_Decommit", _MrmMMsg_0002,
Packit b099d7
			  NULL, NULL, MrmNOT_VALID) ;
Packit b099d7
Packit b099d7
  if ((buffer->access == URMWriteAccess) && (buffer->modified == TRUE))
Packit b099d7
    {
Packit b099d7
      result = Idb__FU_PutBlock (buffer->cur_file->lowlevel_id,
Packit b099d7
				 buffer->IDB_record->header.record_num,
Packit b099d7
				 (char*)buffer->IDB_record) ;
Packit b099d7
      if ( result != MrmSUCCESS )
Packit b099d7
        return Urm__UT_Error ("Idb__BM_Decommit", _MrmMMsg_0004,
Packit b099d7
			      NULL, NULL, MrmNOT_VALID) ;
Packit b099d7
      buffer->cur_file->put_count++ ;
Packit b099d7
Packit b099d7
      buffer->activity = 0;
Packit b099d7
      buffer->modified = FALSE;
Packit b099d7
    }
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
 *	Idb__BM_DecommitAll decommits all the buffers currently allocated
Packit b099d7
 *	for a file. It returns an error immediately if there is any
Packit b099d7
 *	problem decommitting any buffer.
Packit b099d7
 *
Packit b099d7
 *	Since this routine removes all buffers for a file in prepration
Packit b099d7
 *	for closing it, it also wipes out the file pointer in each buffer.
Packit b099d7
 *
Packit b099d7
 *  FORMAL PARAMETERS:
Packit b099d7
 *
Packit b099d7
 *	file_id		IDB file for which to write all modified buffers
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__BM_DecommitAll (IDBFile		file_id)
Packit b099d7
{
Packit b099d7
Packit b099d7
  /*
Packit b099d7
   *  Local variables
Packit b099d7
   */
Packit b099d7
  Cardinal		result ;	/* function result */
Packit b099d7
  Cardinal		ndx ;		/* loop variable		*/
Packit b099d7
  IDBRecordBufferPtr	curbuf ;	/* ptr to element in buff pool	*/
Packit b099d7
Packit b099d7
  if ( idb__buffer_pool_vec == NULL )
Packit b099d7
    return MrmFAILURE;
Packit b099d7
Packit b099d7
  for ( ndx=0,curbuf=idb__buffer_pool_vec ;
Packit b099d7
        ndx
Packit b099d7
        ndx++,curbuf++ )
Packit b099d7
    {
Packit b099d7
      if (curbuf->cur_file == file_id)
Packit b099d7
        {
Packit b099d7
	  result = Idb__BM_Decommit (curbuf) ;
Packit b099d7
	  if ( result != MrmSUCCESS ) return result ;
Packit b099d7
	  curbuf->cur_file = NULL ;
Packit b099d7
        }
Packit b099d7
    }
Packit b099d7
Packit b099d7
  return MrmSUCCESS ;
Packit b099d7
Packit b099d7
}
Packit b099d7