IRAS.h

// IRAS.h
//
// Author David Barrett-Lennard
// (C)opyright Cedanet Pty Ltd 2004

#ifndef Ceda_cxLss_IRAS_H
#define Ceda_cxLss_IRAS_H

#include "cxLss.h"
#include "Ceda/cxUtils/cxUtils.h"
#include "Ceda/cxUtils/BasicTypes.h"
#include "Ceda/cxUtils/OpenMode.h"

namespace ceda
{
/*
Random access store.

Can be implemented by a file or a raw partition.  Assumes that the secondary store is a large 
addressable block of memory.

For performance it should be read or written in large chunks at a time
*/

typedef int64 RASAddress;
typedef RASAddress RASSize;

///////////////////////////////////////////////////////////////////////////////////////////////////
// IRAS

// The following interface is threadsafe, and all calls are serialised.  This means that it is not 
// possible to concurrently read or write different parts of the store.

// A RAS doesn't support concurrent reading and writing because a physical disk only has one head.  
// Furthermore,  this restriction is implicit in the concept of the "current file seek position" on a 
// file that has been opened.

struct IRAS
{
    virtual ~IRAS() {}

    // Represents the unit of I/O - i.e. the disk sector size
    // All I/O is non-buffered and must be in units of the sector size
    virtual int GetDiskSectorSize() const = 0;

    // Allocate memory blocks that are suitable for Read() and Write() calls because they are aligned 
    // on sector boundaries.
    virtual void* AllocateMemoryBlock(int size) = 0;
    virtual void FreeMemoryBlock(void* p) = 0;

    // The RAS should be explicitly closed when it is no longer required
    virtual void Close() = 0;

    // Read a block from the store into the given buffer
    // The range must comply with the current size of the store
    // Throws exceptions on error
    virtual void Read(void* buffer, RASAddress offset, int numBytes) = 0;

    // Write a buffer to the store.  The size of the file will automatically grow if necessary
    // to include the given range.
    // Throws exceptions on error
    // Note that write caching is not employed.  The data is flushed synchronously by this function
    virtual void Write(const void* buffer, RASAddress offset, int numBytes) = 0;

    // Get the total size of the store
    virtual RASSize GetSize() const = 0;

    // Set the size of the store.  
    virtual void TruncateSize(RASSize newSize) = 0;

    virtual void StopWriting() = 0;
};

///////////////////////////////////////////////////////////////////////////////////////////////////
// Implementation of IRAS using a file

// enableFileBuffering indicates whether Windows OS file buffering is enabled for the RAS.
//
// If enableCreate = false then only an existing file can be opened.  I.e. a new file cannot be 
// created.  Therefore if the file doesn't exist a FileException will be thrown.
//
// CreateFileRAS() never returns nullptr.

cxLss_API IRAS* CreateFileRAS(ConstStringZ filename, EOpenMode openMode, bool enableFileBuffering, bool enableWriteThrough) cxThrow1(FileException);

///////////////////////////////////////////////////////////////////////////////////////////////////
// Implementation of IRAS that holds all segments in memory.  Useful for units tests, or where the
// size of the store is limited and it is reasonable for it to be transient.

class PagedBuffer;
cxLss_API IRAS* CreateMemRAS(PagedBuffer& pb);

} // namespace ceda

#endif // include guard