/**********************************************************************
 * Copyright (c) 2005, 2007 IBM Corporation and others.
 * All rights reserved.   This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * $Id: ossrambo.h,v 1.8 2007/03/19 03:14:37 rsmith Exp $
 *
 * Contributors:
 * IBM - Initial API and implementation
 **********************************************************************/

/*******************************************************************************

   Source File Name = ossrambo.h

   Descriptive Name = OSSe RApid Memory Buffer Out (RAMBO)

   Function:
      Defines:

   Dependencies:
      None

   Restrictions:
      None

   Change Activity:
   Defect Date        Who Description
   ====== =========== === ==============================================
   164204 Jan/15/2001 jpk Initial drop
   171596 Apr/05/2001 dns Added prototype for ossRamboStopFlusher
   172892 May/01/2001 dns Added prototype for ossRamboFlushFullChunkstToFunc and
                          flushedCount counter to OSSRamboChunkCB
   194539 Jan/24/2002 dns changed slot copy routines to return OSSErr
   186134 Mar/01/2002 dns use new atomic types
   198075 Mar/05/2002 dns Changed ossRamboFlushFD to ossRamboFlushToFD
   216026 Jul/23/2002 dns Added writers field to OSSRambo structure

   Last Changed =    02/08/27  12:31:32

*******************************************************************************/

#ifndef OSSRAMBO_HEADER_INCLUDED
#define OSSRAMBO_HEADER_INCLUDED

#include "oss.h"
#ifndef ENW
#include "osserror.h"
#include "ossdebug.h"
#include "osstime.h"
#include "ossipcmemory.h"
#else
#include "ossatomictype.h"   /* 186134 */
#endif

/******************************************************************************
   BEGIN TEMPORARY CODE
******************************************************************************/


/* Cache line size definitions */
#ifndef SQLO_TYPICAL_CACHE_LINE
#if defined _AIX
#define SQLO_TYPICAL_CACHE_LINE  128
#elif defined HPUX || defined SQLSUN
#define SQLO_TYPICAL_CACHE_LINE  64
#else
#define SQLO_TYPICAL_CACHE_LINE  128
#endif
#endif

/******************************************************************************
   END TEMPORARY CODE
******************************************************************************/

/* Eye catchers */
#define OSS_RAMBO_EYE_CATCHER_SIZE  8
   /* Actually 8 characters in size with no terminating null character */
#define OSS_RAMBO_RAMBOCB_EYE       "RAMBOCB!"
#define OSS_RAMBO_CHUNKCB_EYE       "RAMBOCH!"
#define OSS_RAMBO_ONDISKCB_EYE      "RAMBOST!"

/*
 * RAMBO SLOTS, CHUNKS, AND BUFFER SIZES
 * The RAMBO buffer is divided into "chunks".  Chunks contain mutliple "slots".
 * For optimial I/O performance, the auto-flusher does not write individual slots
 * to disk.  Instead, it only writes entire chunks to disk.  The chunk size
 * was selected for optimal output * disk performance.  Also, the chunk size
 * must be a power of 2.  This case 128KB is 2^17.
 */
#define OSS_RAMBO_SLOT_SIZE         ((size_t)32)      /* 2^5 bytes */
#define OSS_RAMBO_CHUNK_SIZE        ((size_t)131072)  /* 128KB = 2^17 bytes */
/*#define OSS_RAMBO_CHUNK_SIZE        ((size_t)65536)    64KB = 2^16 bytes */
/*#define OSS_RAMBO_CHUNK_SIZE        ((size_t)32768)    32KB = 2^15 bytes */
/*#define OSS_RAMBO_CHUNK_SIZE        ((size_t)8192)     2^13 bytes */

/*
 * The RAMBO buffer size MUST ALWAYS be a power of 2 and
 * multiple of chunk size.
 */
#define OSS_RAMBO_BUFFER_SIZE_MIN   OSS_RAMBO_CHUNK_SIZE
#define OSS_RAMBO_BUFFER_SIZE_MAX   ((size_t)(1*1024*1024*1024))  /* 2^30 */

#define OSS_RAMBO_ROUND_SLOT_SIZE(size) \
   (((size) + OSS_RAMBO_SLOT_SIZE - 1) & ~(OSS_RAMBO_SLOT_SIZE - 1))

#define OSS_RAMBO_SLOTS_PER_CHUNK         \
      ( OSS_RAMBO_CHUNK_SIZE / OSS_RAMBO_SLOT_SIZE )

/*
 * RAMBO CHUNK CONTROL BLOCKS
 */
#define OSS_RAMBO_SLOT_BITMAP_SIZE  ((size_t)32)
#define OSS_RAMBO_SLOT_BITMAP_ARRAY_SIZE  \
      (OSS_RAMBO_SLOTS_PER_CHUNK / OSS_RAMBO_SLOT_BITMAP_SIZE)

#ifdef ENW
#define OSS_RAMBO_DESCRIPTOR_FILE    1
#define OSS_RAMBO_DESCRIPTOR_SOCKET  2
#endif

typedef struct
{
   /* Cold */
   char eye[OSS_RAMBO_EYE_CATCHER_SIZE] ;

   /* Hot */
/* 186134 - made fillCount and flushedCount OSSAtomic type */
   OSSAtomic fillCount ;
   OSSAtomic flushedCount ;  /* 172892 - number of slots flushed */

   /* A 32-bit integer corresponds to OSS_RAMBO_SLOT_BITMAP_SIZE */
   OSSAtomic slotMap[OSS_RAMBO_SLOT_BITMAP_ARRAY_SIZE] ;     /* 186134 */
} OSSRamboChunkCB ;

/*
 * RAMBO ON DISK CONTROL BLOCK
 * This structure is the header of the memory buffer output file.
 * Make sure there are no pads in this structure!
 */
typedef struct
{
   /* Cold */
   char eye[OSS_RAMBO_EYE_CATCHER_SIZE] ;    /* 8 bytes */
   Uint32 appOnDiskDataSize ;
   Uint32 bufferSize ;
   Uint32 bufferWrapped ;
   Uint32 smallEndian ;
} OSSRamboOnDiskCB ;

/*
 * RAMBO BUFFER CONTROL BLOCK
 */
#define OSS_RAMBO_BUFFER_NAME_SIZE  23

typedef struct
{
   /*
    * The nextSlotIndex is the "hottest" piece of memory in this
    * structure.  It will be atomically incremented during each
    * trace.  To prevent cache "thrashing", I have separated it from
    * the other hot items in this structure by a cache line.
    * To reduce some of the wasted space, I have placed the
    * coldest items after the nextSlotIndex.  These items will be on the
    * same cache line as nextSlotIndex.
    */
   union {
      struct {
         /* Very very hot - Almost all accesses will be writes */
         OSSAtomic nextSlotIndex ;      /* 186134 */

         /* Cold - Very few accesses */
         char eye[OSS_RAMBO_EYE_CATCHER_SIZE] ;
         Sint32 oAppInMemData ;
         Sint32 oAppOnDiskData ;
         char szBufferName[OSS_RAMBO_BUFFER_NAME_SIZE+1] ;
      } h1 ;
      char pad[SQLO_TYPICAL_CACHE_LINE] ;
   } l1 ;

   /*
    * The following items are also very hot in this structure, but
    * rarely take write accesses.  Therefore, I have packed them all
    * together on the same cache line.
    */
   union {
      struct {
         Sint32 oMemBuffer ;
         Sint32 oFirstChunkCB ;
         Sint32 oOnDiskCB ;
         Uint32 status ;
         Uint32 maxSlots ;
         Uint32 maxChunks ;
         Uint32 chunkCBSize ;
      } h2 ;
      char pad[SQLO_TYPICAL_CACHE_LINE] ;
   } l2 ;
} OSSRamboCB ;

#define pFirstChunkCB(pRamboCB) ((OSSRamboChunkCB *)((char *)pRamboCB + pRamboCB->l2.h2.oFirstChunkCB))
#define pOnDiskCB(pRamboCB) ((OSSRamboOnDiskCB *)((char *)pRamboCB + pRamboCB->l2.h2.oOnDiskCB))
#define pMemBuffer(pRamboCB) ((void *)((char *)pRamboCB + pRamboCB->l2.h2.oMemBuffer)) /* 230912 */
#define pAppInMemData(pRamboCB) ((void *)((char *)pRamboCB + pRamboCB->l1.h1.oAppInMemData)) /* 230912 */
#define pAppOnDiskData(pRamboCB) ((void *)((char *)pRamboCB + pRamboCB->l1.h1.oAppOnDiskData)) /* 230912 */


#if 0
/* This is the original OSSRamboCB structure */
typedef struct
{
   /* Cold - Very few accesses */
   char eye[OSS_RAMBO_EYE_CATCHER_SIZE] ;

   /* Hottest - Almost all accesses will be writes */
   sqlo_atomic nextSlotIndex ;

   /* Hot - Most accesses will be reads */
   Uint32 status ;

   /* Hot - Almost all accesses will be reads */
   void * pMemBuffer ;
   OSSRamboChunkCB * pFirstChunkCB ;
   Uint32 maxSlots ;
   Uint32 maxChunks ;

   /* Cold - Very few accesses */
   char szBufferName[OSS_RAMBO_BUFFER_NAME_SIZE+1] ;
   OSSRamboOnDiskCB * pOnDiskCB ;
   void * pAppInMemData ;
   void * pAppOnDiskData ;
   Uint32 chunkCBSize ;
} OSSRamboCB ;
#endif

/*
 * RAMBO HANDLE
 */
typedef struct
{
   OSSRamboCB * pRamboCB ;
   OSSMemRes    ipcMemHandle ;
   OSSAtomic    writers;      /* 216026 */
} OSSRambo ;

/* RAMBO IPC Memory ID */
#define OSS_RAMBO_IPC_MEM_ID        1974

/* RAMBO status flags */
#define OSS_RAMBO_CREATED           (1<<0)   /* RAMBO buffer created */
#define OSS_RAMBO_AUTOF_STARTED     (1<<1)   /* Auto flusher is started */
#define OSS_RAMBO_AUTOF_STOP_NOW    (1<<2)   /* Auto flusher should stop */
#define OSS_RAMBO_FLUSHING          (1<<3)   /* Flushing the buffer */


/* External RAMBO functions */
OSS_EXTERNC OSSErr OSS_API ossRamboCreate( char *, Uint32, Uint32, Uint32,
                                           OSSRambo *, void **, void ** ) ;
OSS_EXTERNC OSSErr OSS_API ossRamboAttach( char *, OSSRambo *, void **,
                                           void ** ) ;
OSS_EXTERNC OSSErr OSS_API ossRamboDestroy( OSSRambo * ) ;
OSS_EXTERNC OSSErr OSS_API ossRamboClose( OSSRambo * ) ;
OSS_EXTERNC OSSErr OSS_API ossRamboAutoFlusherStart( OSSRambo *,
                                                     const char *,
                                                     const char *,
                                                     const char * ) ;
OSS_EXTERNC OSSErr OSS_API ossRamboAutoFlusherStop( OSSRambo * ) ;
/* 194539 - changed the slot copy routines to return an error code */
OSS_EXTERNC OSSErr OSS_API ossRamboSlotCopy( OSSRambo *, const void *,
                                             Uint32 ) ;
OSS_EXTERNC OSSErr OSS_API ossRamboMultiSlotCopy( OSSRambo *, const void *,
                                                  Uint32 ) ;
OSS_EXTERNC OSSErr OSS_API ossRamboFlush( OSSRambo *, const char * ) ;
#ifdef ENW
#include <jni.h>
OSS_EXTERNC OSSErr OSS_API ossRamboFlushToFD( OSSRambo *, int, int ) ;
OSS_EXTERNC OSSErr OSS_API ossRamboFlushToFunc( OSSRambo *, RA_Data_Processing_Routine, void * ) ;
OSS_EXTERNC OSSErr OSS_API ossRamboFlushToStream( OSSRambo *, JNIEnv *, jobject ) ;
OSS_EXTERNC OSSErr OSS_API ossRamboFlushFullChunksToFunc( OSSRambo *, RA_Data_Processing_Routine, void * ) ;
OSS_EXTERNC OSSErr OSS_API ossRamboStopFlusher( OSSRambo * ) ;
OSS_EXTERNC OSSErr OSS_API ossRamboStopFlusherAndDetach( OSSRambo * ) ;
OSS_EXTERNC OSSErr OSS_API ossRamboDetach( OSSRambo * ) ;
#endif

#endif
