/****************************************************************************
**  SIONLIB     http://www.fz-juelich.de/jsc/sionlib                       **
*****************************************************************************
**  Copyright (c) 2008-2015                                                **
**  Forschungszentrum Juelich, Juelich Supercomputing Centre               **
**                                                                         **
**  See the file COPYRIGHT in the package base directory for details       **
****************************************************************************/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <assert.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>


#include "sion.h"
#include "sion_debug.h"
#include "sion_internal.h"
#include "sion_cache.h"


#if defined(_SION_LINUX)
#include <sys/mman.h>
#elif defined(_SION_AIX)
#elif defined(_SION_BGL)
#elif defined(_SION_BGP)
#elif defined(_SION_XT)
#include <sys/types.h>
#include <sys/mman.h>
#include <fcntl.h>           /* For O_* constants */
#endif


/* 

   This functions control and manage a memory based cache for sion
   files. Depending on a set of environment variables the cache will work as
   write-through or as write-back cache. On Unix systems a POSIX shared memory
   segment will be used, on Blue Gene/P it is persistent memory.

   A cache of n MB will store the last n MB of data per task in the cache.  If
   the cache memory is filled, the full cache will be written to disk and the
   cache will be exhausted. 
   
 */

/*!\brief checks if environment variables are set to use cache
 *
 * @param  *sion_filedesc                       sion file description struct (_sion_filedesc)
 *
 * @return SION_SUCCESS if env could be checked
 */
int  _lsion_cache_check_env(_sion_filedesc *sion_filedesc) {
  const char *t;
  int rc = SION_SUCCESS;

  t = _lsion_getenv("SION_CACHESIZE");
  if(t) {
    sion_filedesc->usecache=1;
    sion_filedesc->cachesize=atoi(t);
    sion_filedesc->flag1 |= _SION_FLAG1_USECACHE;
  }
  DPRINTFP((2, "_lsion_cache_check_env", -1, "usecache=%d cachesize=%d flag1=%d\n", sion_filedesc->usecache, sion_filedesc->cachesize, sion_filedesc->flag1));

  return (rc);
}


/*!\brief allocates and initalize the cache
 *
 * @param  *sion_filedesc                       sion file description struct (_sion_filedesc)
 *
 * @return SION_SUCCESS if ok
 */
int  _lsion_cache_init(_sion_filedesc *sion_filedesc) {
  int rc = SION_SUCCESS;

  /* allocation */
  if(sion_filedesc->usecache) {
    if(sion_filedesc->mode == SION_FILEMODE_WRITE) { 
#if defined(_SION_LINUX)
      rc=_lsion_cache_create_linux(sion_filedesc);
#elif defined(_SION_AIX)
#elif defined(_SION_BGL)
#elif defined(_SION_BGP)
#elif defined(_SION_XT)
#endif
    } else if(sion_filedesc->mode == SION_FILEMODE_READ) {
#if defined(_SION_LINUX)
      rc=_lsion_cache_load_linux(sion_filedesc);
#elif defined(_SION_AIX)
#elif defined(_SION_BGL)
#elif defined(_SION_BGP)
#elif defined(_SION_XT)
#endif
    } else {
      _lsion_errorprint(SION_NOT_SUCCESS,_SION_ERROR_RETURN,"_lsion_cache_init: unknown SION mode\n");
    }
  }

  return (rc);
}


/*!\brief deallocates 
 *
 * @param  *sion_filedesc                       sion file description struct (_sion_filedesc)
 *
 * @return SION_SUCCESS if ok
 */
int  _lsion_cache_destroy(_sion_filedesc *sion_filedesc) {
  int rc = SION_SUCCESS;

  /* deallocation */
  if(sion_filedesc->usecache) {
#if defined(_SION_LINUX)
    rc=_lsion_cache_destroy_linux(sion_filedesc);
#elif defined(_SION_AIX)
#elif defined(_SION_BGL)
#elif defined(_SION_BGP)
#elif defined(_SION_XT)
#endif
  }

  return (rc);
}

/*!\brief allocates cache for linux
 *
 * @param  *sion_filedesc                       sion file description struct (_sion_filedesc)
 *
 * @return SION_SUCCESS if ok
 */
int  _lsion_cache_create_linux(_sion_filedesc *sion_filedesc) {
  int rc = SION_SUCCESS;

  return(rc);
}

/*!\brief loads a already allocated cache for linux
 *
 * @param  *sion_filedesc                       sion file description struct (_sion_filedesc)
 *
 * @return SION_SUCCESS if ok
 */
int  _lsion_cache_load_linux(_sion_filedesc *sion_filedesc) {
  int rc = SION_SUCCESS;

  return(rc);
}


/*!\brief deallocates cache for linux
 *
 * @param  *sion_filedesc                       sion file description struct (_sion_filedesc)
 *
 * @return 1 if ok
 */
int  _lsion_cache_destroy_linux(_sion_filedesc *sion_filedesc) {
  int rc = SION_SUCCESS;


  return(rc);
}
