Store.h

// Store.h
//
// Author David Barrett-Lennard
// (C)opyright Cedanet Pty Ltd 2012

#include "Ceda/cxUtils/TracerUtils.h"
#include "Ceda/cxUtils/FileException.h"
#include "Ceda/cxLss/ILogStructuredStore.h"
@import "Ceda/cxPersistStore/IPersistStore.h"

struct Store
{
    explicit Store(const ceda::xstring& path, ceda::EOpenMode openMode = ceda::OM_OPEN_ALWAYS) : 
        m_path(path),
        m_store(NULL),
        m_pspace(NULL)
    {
        Open(openMode);
    }
    
    ~Store()
    {
        Close();
    }

    void Open(ceda::EOpenMode openMode = ceda::OM_OPEN_ALWAYS)
    {
        cxAssert(!m_store);
        cxAssert(!m_pspace);
        
        m_store = ceda::OpenPersistStore(m_path.c_str(),openMode);
        m_pspace = ceda::OpenPSpace(m_store, "P");
        ceda::SetThreadPtr<ceda::PSpace>(m_pspace);
        ceda::SetThreadPtr<ceda::CSpace>(GetCSpace(m_pspace));
    }
    
    template <typename T>
    T* BootstrapRoot()
    {
        return ceda::BootstrapPSpaceRoot<T>("R");
    }
    
    void Close()
    {
        ceda::SetThreadPtr<ceda::CSpace>(NULL);
        ceda::SetThreadPtr<ceda::PSpace>(NULL);
        if (m_pspace)
        {
            ceda::Close(m_pspace);
            m_pspace = NULL;
        }        
        if (m_store)
        {
            ceda::Close(m_store);
            m_store = NULL;
        }        
    }

    ceda::ssize_t GetNumPSpaces() const
    {
        return ceda::GetNumPSpaces(m_store);
    }
    
    ceda::ssize_t GetNumPersistableObjects() const
    {
        return ceda::GetNumPersistableObjects(m_store);
    }

    void GetLssStats(ceda::LssStats& stats) const
    {
        // Before getting stats on the LSS we flush dirty objects in the PSpace.
        
        // Ensure that all dirty objects in the PSpace are written to the LSS using a single LSS 
        // transaction.  If flushToDisk = true then the LSS transaction is also flushed to disk 
        // before this function returns.
        // Must be called without a lock on the PSpace
        cxAssert(m_pspace);
        bool flushToDisk = true;
        WriteDirtyObjectsToLss(m_pspace, flushToDisk);
        
        GetLss(m_store)->GetStats(stats);
    }

    void ShowLssStats() const
    {
        ceda::LssStats stats;
        GetLssStats(stats);

        ceda::TracerX os;
        WriteLssStats(os,stats);
    }

    ceda::xstring m_path;
    ceda::PersistStore* m_store;
    ceda::PSpace* m_pspace;
};