/*---------------------------------------------------------------*/
/*   Copyright (c) 1992 Regents of the University of California  */
/*                 All Rights Reserved                           */
/*-------------------------- ------------------------------------*/
/*
      @(#)BufMalloc.c	1.3  (UCLA, IGPP) 20 Apr 1994 
*/
/*---------------------------------------------------------------
  BufMalloc(int size) -
    Safer malloc, if your list is taking up all the avaliable space
    and you need more, this function will move some of the records
    to file storage on that the malloc can happen.
 
  Return:
    char* area of memory, show be changed to void* under ANSI C.
 
  Entry Requirements:
    int size, should be changed to a size_t under ANSI C.
 
  Development History:
    Began: 09/17/93 - Gilbert Hyatt.
    Edited:04/14/94 - Gilbert Hyatt 
      Now uses pipec.h as entry point into the library.
  ---------------------------------------------------------------*/
#include <malloc.h>
#include "pipec.h"

extern BUFFER_HEAD  _Rbuffer;
RECPTR              *ptr;

char*
BufMalloc(size)
int size;
{
  char                *dataptr;
  int                 TEST;

int          wtest;  
BUFFER_HEAD  TRbuffer;
memcpy(&TRbuffer, &_Rbuffer, sizeof(BUFFER_HEAD));

  TEST = FALSE;
  _Rbuffer.num_lastVMrec  = (_Rbuffer.num_lastVMrec)?_Rbuffer.num_lastVMrec:1;
  ptr                     = (_Rbuffer.num_lastVMrec)?_Rbuffer.lastVMrec    :_Rbuffer.end;

  if (size == _Rbuffer.recl) {
    _Rbuffer.data_space_used  += _Rbuffer.recl;
    TEST = (_Rbuffer.data_space_used > BUF_DATA_MAX_SPACE)?TRUE:FALSE;
  }  /* end of if */

  if (TEST)                               ShiftOutRec();
  while((dataptr = malloc(size)) == NULL) ShiftOutRec();

  return(dataptr);
}  /*end of BufMalloc() */


ShiftOutRec()
{
  int DO_WORK;

  DO_WORK = TRUE;
  while(DO_WORK) {
    ptr = ptr->next; 
    _Rbuffer.num_lastVMrec++;
    _Rbuffer.lastVMrec = ptr;
    if (ptr == _Rbuffer.end) {_Rbuffer.num_lastVMrec = BufNoValue; return(NULL);}

    if (ptr->vmrecnum == BufRealMem) {
      _Rbuffer.num_in_outpage++;
      memcpy((_Rbuffer.outpage + _Rbuffer.recl * (_Rbuffer.num_in_outpage -1)), ptr->data, _Rbuffer.recl);
      free(ptr->data);
      ptr->vmrecnum = (_Rbuffer.num_outpage * _Rbuffer.recs_per_page) + _Rbuffer.num_in_outpage;
      _Rbuffer.data_space_used  -= _Rbuffer.recl;
      if (_Rbuffer.num_in_outpage == _Rbuffer.recs_per_page) {
	fseek(_Rbuffer.vmfilename, 0L, 2);
	fwrite(_Rbuffer.outpage, _Rbuffer.pagesize, 1, _Rbuffer.vmfilename);
	_Rbuffer.num_in_outpage = 0;
	_Rbuffer.num_outpage++;
      }  /* end of if */
      DO_WORK = FALSE;
    }  /* end of if */
  }  /* end of while */
}  /* end of ShiftOutRec() */






