/*!**************************************************************************

    module      : Log_RecordColumnMap.hpp

    -------------------------------------------------------------------------

    author      : JuergenA
    responsible : UweH

    special area: Logging
    description : defines a class containing the description and the value of fixed/var/longvar columns

    last changed: 2001-04-12

    -------------------------------------------------------------------------

    copyright:    (c) 2000-2004 SAP AG


    ========== licence begin  GPL
    Copyright (c) 2000-2005 SAP AG

    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
    as published by the Free Software Foundation; either version 2
    of the License, or (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
    ========== licence end




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


#ifndef LOG_RECORD_COLUMN_MAP_H
#define LOG_RECORD_COLUMN_MAP_H

/*===========================================================================*
 *  INCLUDES                                                                 *
 *===========================================================================*/

#include "Logging/Log_IRecordColumnMap.hpp"

#include "SAPDBCommon/SAPDB_Types.hpp"
#include "SAPDBCommon/MemoryManagement/SAPDBMem_IRawAllocator.hpp"
#include "KernelCommon/Kernel_VTrace.hpp"
#include "Logging/Log_Types.hpp"
#include "Logging/Log_ReadWriteActionImage.hpp"
#include "ggg00.h"


/*===========================================================================*
 *  STRUCTURES, TYPES, UNIONS ...                                   *
 *===========================================================================*/

typedef enum
{
        Log_FixKeyColumn,
        Log_VarKeyColumn,
        Log_FixColumn,
        Log_VarColumn,
        Log_VarLongColumn,
		// Log_Column, +++ UH do not uncomment until rest of code is updated +++
        Log_ColumnLastEnum,  
        Log_NilColumn
} Log_ColumnType;

/*!-------------------------------------------------------------------------
declaration:  Log_ColumnType
--------------------------------------------------------------------------*/
extern const char* Log_ColumnTypeStrings[Log_NilColumn+1];

/*==========================================================================*
*  CLASSES                                                                  * 
*===========================================================================*/

//===================================================================================
/*! class:       Log_ColumnEntry

    description: one entry of a column list
*/
class Log_ColumnEntry
{
private:

    SAPDB_Int4              m_OffsetOrNumber;
    SAPDB_Int4              m_ValueLength;
    const SAPDB_Byte       *m_pValue;
    SAPDB_Byte             *m_pAllocatedValue;
    SAPDBMem_IRawAllocator *m_pAllocator;
    Log_ColumnEntry        *m_pNext;

public:
    
    //--------------------------------------------------------------Log_ColumnEntry---
    /*! function:     Log_ColumnEntry ctor
    */
    Log_ColumnEntry ()
    : m_OffsetOrNumber  (0),
      m_ValueLength     (0),
      m_pValue          (NULL),
      m_pAllocatedValue (NULL),
      m_pNext           (NULL),
      m_pAllocator      (NULL)
    { }

    //--------------------------------------------------------------Log_ColumnEntry---
    /*! function:     ~Log_ColumnEntry ctor
    */
    ~Log_ColumnEntry()
    {
        if ( m_pAllocator != 0 )
        {
            m_pAllocator->Deallocate(m_pAllocatedValue);
        }
    }
    
    //--------------------------------------------------------------Log_ColumnEntry---
    /*! function:    AllocateAndInitFixCol
    
        description: allocate an entry and initializes it
  
        arguments:   RawAllocator   [in out] used to allocate a value with trailing defined bytes
                     ColumnOffset   [in]     the offset of the fixed column behing the record key 
                     FixedColumnLen [in]     the length of the fixed column contained in the record
                     ValueLength    [in]     the truncated length of the new value
                     pValue         [in]     the pointer to the new value
                     Error          [out]
    */
    void AllocateAndInitFixCol (
        SAPDBMem_IRawAllocator &RawAllocator,
        SAPDB_Int4              ColumnOffset,
        SAPDB_Int4              FixedColumnLen,
        SAPDB_Int4              ValueLength,
        const SAPDB_Byte       *pValue,
        tgg00_BasisError       &Error);

    //--------------------------------------------------------------Log_ColumnEntry---
    /*! function:    AllocateAndInitUndefCol
    
        description: allocate an entry and initializes it as an undef column
  
        arguments:   RawAllocator   [ref] used to allocate the undef value
                     OffsetOrNumber [in]  the offset or the number of the column
                     FixedColumnLen [in]  the length of a fixed column otherwise zero
                     Error          [out]
    */
    void AllocateAndInitUndefCol (
        SAPDBMem_IRawAllocator &RawAllocator,
        SAPDB_Int4              OffsetOrNumber,
        SAPDB_Int4              FixedColumnLen,
        tgg00_BasisError       &Error);

    //--------------------------------------------------------------Log_ColumnEntry---
    /*! function:     GetLength
    
        return value: the length of the column
    */
    SAPDB_Int4 GetLength () const
    { 
        return (m_ValueLength);
    }  

    //--------------------------------------------------------------Log_ColumnEntry---
    /*! function:     GetNumber
    
        return value: the number of the variable column
    */
    SAPDB_Int4 GetNumber () const
    { 
        return (m_OffsetOrNumber);
    }

    //--------------------------------------------------------------Log_ColumnEntry---
    /*! function:     GetNext
    
        return value: the pointer to the following column entry
    */
    Log_ColumnEntry *GetNext () const
    { 
        return (m_pNext);
    }  

    //--------------------------------------------------------------Log_ColumnEntry---
    /*! function:     GetOffset
    
        return value: the offset of the fixed column behind the key
    */
    SAPDB_Int4 GetOffset () const
    { 
        return (m_OffsetOrNumber);
    }

    //--------------------------------------------------------------Log_ColumnEntry---
    /*! function:     GetValue
    
        return value: pointer to the new value of the column
    */
    const SAPDB_Byte *GetValue () const
    { 
        return (m_pValue);
    }

    //--------------------------------------------------------------Log_ColumnEntry---
    /*! function:    Init
    
        description: initializes the column Entry without allocation

        arguments:   OffsetOrNumber [in] the offset or the number of the column
                     ValueLength    [in]  
                     pValue         [in]
    */
    void Init (SAPDB_Int4        OffsetOrNumber,
               SAPDB_Int4        ValueLength,
               const SAPDB_Byte *pValue)
    {
        m_OffsetOrNumber = OffsetOrNumber;
        m_ValueLength    = ValueLength;
        m_pValue         = pValue;
    }

    
    //--------------------------------------------------------------Log_ColumnEntry---
    /*! function:    Insert
    
        description: inserts this entry into the map
      
        arguments:   pPrevEntry      [in]     inserts the entry behind PrevEntry
                     pFirstListEntry [in out]
    */
    void Insert (
        Log_ColumnEntry *pPrevEntry,
        Log_ColumnEntry *&pFirstListEntry);
    
    //--------------------------------------------------------------Log_ColumnEntry---
    /*! function:    IsGreater operator
    
        return value: true, if this entry is greater than the other entry
      
        arguments:   OtherEntry [in] 
    */
    bool operator > (const Log_ColumnEntry &OtherEntry) const
    {
        return (this->m_OffsetOrNumber > OtherEntry.m_OffsetOrNumber);
    }
    
    //--------------------------------------------------------------Log_ColumnEntry---
    /*! function:    Remove
    
        description: removes this entry from the map
      
        arguments:   pPrevEntry      [in]     removes the entry behind PrevEntry
                     pFirstListEntry [in out]
    */
    void Remove (
        Log_ColumnEntry *pPrevEntry,
        Log_ColumnEntry *&pFirstListEntry);


    //--------------------------------------------------------------Log_ColumnEntry---
    /*! function:    WritetoTrace
    */
    void WriteToTrace(const char *title = NULL) const;
};
/*! endclass: Log_ColumnEntry */

//===================================================================================
/*! class:       Log_ColumnList

    description: a double chained list of column entries without any allocation
*/
class Log_ColumnList
{
private:
    
    Log_ColumnEntry *m_pFirst;
    SAPDB_Int4       m_EntryCount;
    SAPDB_Int4       m_SumValueLength;
    Log_ColumnType   m_ColumnType;
    
public:
    
    //--------------------------------------------------------------Log_ColumnList---
    /*! function:    Log_ColumnList ctor
    */
    Log_ColumnList ()
    : m_pFirst         (NULL),
      m_EntryCount     (0),
      m_SumValueLength (0),
      m_ColumnType     (Log_NilColumn)
    { }
    

    //--------------------------------------------------------------Log_ColumnList---
    /*! function:     GetColumnType
    
        return value: the type of the columns contained in this list
    */
    Log_ColumnType GetColumnType () const
    {
        return (m_ColumnType);
    }

    //--------------------------------------------------------------Log_ColumnList---
    /*! function:     GetEntryCount
    
        return value: the pointer to the first entry of the list
    */
    SAPDB_Int4 GetEntryCount () const
    {
        return (m_EntryCount);
    }

    //--------------------------------------------------------------Log_ColumnList---
    /*! function:     GetFirst
    
        return value: the pointer to the first entry of the list
    */
    Log_ColumnEntry *GetFirst () const
    {
        return (m_pFirst);
    }

    //--------------------------------------------------------------Log_ColumnList---
    /*! function:     GetSumValueLength
    
        return value: the pointer to the first entry of the list
    */
    SAPDB_Int4 GetSumValueLength () const
    {
        return (m_SumValueLength);
    }

    //--------------------------------------------------------------Log_ColumnList---
    /*! function:    Init
    */
    void Init (Log_ColumnType ColumnType)
    {
        this->m_ColumnType = ColumnType;
    }
    

    //--------------------------------------------------------------Log_ColumnList---
    /*! function:    InsertOnTop
    
        description: Inserts a column entry in front of the column list (for fixed columns only)
        
        arguments:   pEntry [in] the pointer to the entry to be inserted
    */
    void InsertOnTop (Log_ColumnEntry *pEntry)
    {
        pEntry->Insert (NULL, this->m_pFirst);
    
        ++this->m_EntryCount;
    
        this->m_SumValueLength += pEntry->GetLength();
    }

    //--------------------------------------------------------------Log_ColumnList---
    /*! function:    InsertSorted
    
        description: Inserts a column entry into the sorted column list (for variable columns)
        
        arguments:   pEntry [in] the pointer to the entry to be inserted
    */
    void InsertSorted (Log_ColumnEntry *pEntry);
    
    //--------------------------------------------------------------Log_ColumnList---
    /*! function:     IsEmpty
    
        return value: true, if the list is empty
    */
    bool IsEmpty () const
    {
        return (NULL == m_pFirst);
    }

    //--------------------------------------------------------------Log_ColumnList---
    /*! function:    Remove
    
        description: Removes a column entry from the column list
        
        arguments:   pEntry     [in]
                     pPrevEntry [in]
    */
    void Remove (Log_ColumnEntry *pEntry,
                 Log_ColumnEntry *pPrevEntry)
    {
        this->m_SumValueLength -= pEntry->GetLength();
    
        pEntry->Remove (pPrevEntry, this->m_pFirst);
    
        --this->m_EntryCount;
    }

    //--------------------------------------------------------------Log_ColumnList---
    /*! function:    WritetoTrace
    */
    void WriteToTrace(const char *title = NULL) const
    {
        Kernel_VTrace trace;
        if ( title != NULL )
            trace << title << FlushLine;
        trace << "Type: " << Log_ColumnTypeStrings[m_ColumnType] << " "
              << m_EntryCount << " entries, SumValueLength: " << m_SumValueLength
              << FlushLine;
        Log_ColumnEntry *currEntry      = m_pFirst;
        SAPDB_Int        currEntryCount = 0;
        while ( currEntry != NULL
                &&
                currEntryCount <= m_EntryCount )
        {
            currEntry->WriteToTrace();
            currEntry = currEntry->GetNext();
            ++currEntryCount;
        }
    }
};
/*! endclass: Log_ColumnList */


//===================================================================================
/*! class:       Log_RecordColumnMap

    description: a list containing the description and the value of fixed/var/longvar columns
*/

class Log_RecordColumnMap: public Log_IRecordColumnMap, public Log_ReadWriteActionImage
{
    
private:
    
    struct PersistentColEntry
    {
        SAPDB_UInt2 OffsetOrNumber;
        SAPDB_UInt2 ValueLength;
    };

    struct RecColMapEntryHeader
    {
        SAPDB_Int4     ImageLen;
        SAPDB_Int4     LengthAllValues;
        SAPDB_UInt2    ImageEntries;
        SAPDB_UInt2    FixColCnt;
        SAPDB_UInt2    VarColCnt;
        SAPDB_UInt2    VarLongColCnt;
        RecColMapEntryHeader()
        {
            ImageLen        = 0;
            LengthAllValues = 0;
            ImageEntries    = 0;
            FixColCnt       = 0;
            VarColCnt       = 0;
            VarLongColCnt   = 0;
        }
        void WriteToTrace(const char *title = NULL) const
        {
            Kernel_VTrace trace;
            if ( title != NULL )
                trace << title << FlushLine;
            trace << "ImageLen: "          << ImageLen
                  << ", LengthAllValues: " << LengthAllValues
                  << ", ImageEntries: "    << ImageEntries
                  << FlushLine;
            trace << "FixColCnt: "         << FixColCnt
                  << ", VarColCnt: "       << VarColCnt
                  << ", VarLongColCnt: "   << VarLongColCnt
                  << FlushLine;
        }
    };

    RecColMapEntryHeader    m_EntryHeader;
    SAPDBMem_IRawAllocator *m_pRawAllocator;
    Log_ColumnEntry        *m_pAllocatedMap;
    Log_ColumnList          m_ColList [Log_ColumnLastEnum];
    SAPDB_Int4              m_AllocatedEntries;
    SAPDB_Int4              m_UsedEntries;
    
    SAPDB_Byte             *m_pAllValuesForRead;
    SAPDBMem_IRawAllocator *m_pAllValuesAllocator;

    SAPDB_UInt2             m_PseudoNullValLen;

    //--------------------------------------------------------------Log_RecordColumnMap---
    /*! function:    CalculatePersistentImage
    
        description: initializes the persistent entry header
    */
    void CalculatePersistentImage ();

    //--------------------------------------------------------------Log_RecordColumnMap---
    /*! function:    CreateAnyVarColPart
    
        description: creates a variable [long] column part using the old record and the column map

        arguments:   ColList                [in out] m_VarColList or m_VarLongColList
                     OffsetFollowingOldPart [in out] has to be initialized with FirstVarColOffset
                                                     when calling first time to create the Log_VarColumn part
                     pOldRec    [in]   pointer to the existing record
                     pNewRec    [out]  pointer to the record space reserved to build the new record
                     NewRecSize [in]   size of the record space
                     Error      [out]                   
    */                        
    void CreateAnyVarColPart (
        const Log_ColumnList &ColList,
        SAPDB_Int4           &OffsetFollowingOldPart,
        const tgg00_Rec      *pOldRec,
        tgg00_Rec            *pNewRec,
        SAPDB_Int4            NewRecSize,
        tgg00_BasisError     &Error)     const;

    //--------------------------------------------------------------Log_RecordColumnMap---
    /*! function:    CreateAnyVarColPartAndBeforeImage
    
        description: creates a variable [long] column part using the old record and the column map

                     Redundant columns are removed from this after image and the before image is created. 

        arguments:   ColList                [in out] m_VarColList or m_VarLongColList
                     OffsetFollowingOldPart [in out] has to be initialized with FirstVarColOffset
                                                     when calling first time to create the Log_VarColumn part
                     pOldRec     [in]     pointer to the existing record
                     pNewRec     [out]    pointer to the record space reserved to build the new record
                     NewRecSize  [in]     size of the record space
                     BeforeImage [in out] 
                     Error       [out]                   
    */                         
    void CreateAnyVarColPartAndBeforeImage (
        Log_ColumnList      &ColList,
        SAPDB_Int4          &OffsetFollowingOldPart,
        const tgg00_Rec     *pOldRec,
        tgg00_Rec           *pNewRec,
        SAPDB_Int4           NewRecSize,
        Log_RecordColumnMap &BeforeImage,
        tgg00_BasisError    &Error);

    //--------------------------------------------------------------Log_RecordColumnMap---
    /*! function:    CreateFixColPartAndBeforeImage
    
        description: creates the part of fixed columns using the old record and the column map

                     Redundant columns are removed from this after image and the before image is created.
                     If a key column is altered, the error e_key_update occurres and a delete of the
                     old record and an insert of the created new record has to be triggered.

        arguments:   pOldRec     [in]     pointer to the existing record
                     pNewRec     [out]    pointer to the record space reserved to build the new record
                     NewRecSize  [in]     size of the record space
                     BeforeImage [in out]
                     Error       [out]                   
    */  
    void CreateFixColPartAndBeforeImage (
        const tgg00_Rec     *pOldRec,
        tgg00_Rec           *pNewRec,
        SAPDB_Int4           NewRecSize,
        Log_RecordColumnMap &BeforeImage,
        tgg00_BasisError    &Error);
    
    
    //--------------------------------------------------------------Log_RecordColumnMap---
    /*! function:    CreateKeyAndFixColPart
    
        description: creates the header, the key and the fixed columns using the old record and the map

        arguments:   pOldRec         [in]  pointer to the existing record
                     pNewRec         [out] pointer to the record space reserved to build the new record
                     WithoutVarParts [in]  indicates, that the entry does not know anything about var parts
                     Error           [out]                   
    */  
    void CreateKeyAndFixColPart (
        const tgg00_Rec  *pOldRec,
        tgg00_Rec        *pNewRec,
        bool              WithoutVarParts,
        tgg00_BasisError &Error)         const;

    //--------------------------------------------------------------Log_RecordColumnMap---
    /*! function:    CreateKeyPart
    
        description: creates the part of key columns using the old record and the column map

                     Redundant columns are removed from this after image.
                     This function does not create any before image.
                     If a key column is altered, the flag KeyUpdated is set.

        arguments:   pOldRec    [in]  pointer to the existing record
                     pNewRec    [out] pointer to the record space reserved to build the new record
                     NewRecSize [in]  size of the record space
                     KeyUpdated [out]
                     Error      [out]                   
    */  
    void CreateKeyPart (
        const tgg00_Rec  *pOldRec,
        tgg00_Rec        *pNewRec,
        SAPDB_Int4        NewRecSize,
        bool             &KeyUpdated,
        tgg00_BasisError &Error);
    
    //--------------------------------------------------------------Log_RecordColumnMap---
    /*! function:     GetFreeEntry
    
        return value: the pointer to a free column entry
    */    
    Log_ColumnEntry* GetFreeEntry ()
    {
        if (this->m_UsedEntries >= this->m_AllocatedEntries) return (NULL);
        
        ++ this->m_UsedEntries;
        
        return (this->m_pAllocatedMap + this->m_UsedEntries - 1);
    }

    //--------------------------------------------------------------Log_RecordColumnMap---
    /*! function:    InsertValue
    
        description: inserts a value except key values into the specified list
  
                     This function is used to create a before image of a column
                     or to insert a column created by CreateColDescForExistingNewRec.

        arguments:   ColumnType     [in]
                     OffsetOrNumber [in] the offset or the number of the column
                     ValueLength    [in]  
                     pValue         [in]
                     Error          [out]
    */
    void InsertValue (
        Log_ColumnType    ColumnType,
        SAPDB_Int4        OffsetOrNumber,
        SAPDB_Int4        ValueLength,
        const SAPDB_Byte *pValue,
        tgg00_BasisError &Error);

    //--------------------------------------------------------------Log_RecordColumnMap---
    /*! function:    InsertVarUndefValue
    
        description: inserts an variable undef value into the specified variable column list

                     This function is used to create a before image of a column which does not exist
                     in the old record.

        arguments:   ColumnType     [in]
                     OffsetOrNumber [in] the offset or the number of the column
                     Error          [out]
    */
    void InsertVarUndefValue (
        Log_ColumnType    ColumnType,
        SAPDB_Int4        OffsetOrNumber,
        tgg00_BasisError &Error);
    
protected:
    
    //--------------------------------------------------------------Log_RecordColumnMap---
    /*! function:    Log_RecordColumnMap ctor
    
        arguments:   ActionType [in]
    */
    Log_RecordColumnMap (Log_ActionType ActionType);
    
    //--------------------------------------------------------------Log_RecordColumnMap---
    /*! function:    ~Log_RecordColumnMap
    
        description: deallocate the column lists
    */
    ~Log_RecordColumnMap ();

    //--------------------------------------------------------------Log_RecordColumnMap---
    /*! function:     AddNullValLen
    
        return value: the length for the NULL-values not existing in record
    */
    void AddNullValLen (const SAPDB_Int4 NullValLen) 
    {
        m_PseudoNullValLen += NullValLen;
    }

    //--------------------------------------------------------------Log_RecordColumnMap---
    /*! function:    CreateColDescForExistingNewRec
    
        description: allocates and inserts columns specifying the difference between the old and new record
        
                     This function applies to the after image and creates a corresponding before image.
        
        arguments:   RawAllocator [ref]
                     pOldRecord   [in]
                     pNewRecord   [in]     the values of the created column entries point into this record 
                     BeforeImage  [in out] corresponding before image
                     IsOk         [out]
    */
    void CreateColDescForExistingNewRec (
        SAPDBMem_IRawAllocator &RawAllocator,
        const tgg00_Rec        *pOldRecord,
        const tgg00_Rec        *pNewRecord,
        Log_RecordColumnMap    &BeforeImage,
        tgg00_BasisError       &Error);

    //--------------------------------------------------------------Log_RecordColumnMap---
    /*! function:    CreateNewRecord

        description: creates the new record in case of undo or redo

        arguments:   pOldRec    [in]  pointer to the existing record
                     pNewRec    [out] pointer to the new record. The Length has to be initialized. 
                     Error      [out]
    */
    void CreateNewRecord (
        const tgg00_Rec  *pOldRec,
        tgg00_Rec        *pNewRec,
        tgg00_BasisError &Error)     const;

    //--------------------------------------------------------------Log_RecordColumnMap---
    /*! function:    CreateNewRecordAndBeforeImage

        description: creates the new record using the old record and the after image column map
         
                     This function applies to the after image and creates a corresponding before image.

                     Redundant columns are removed from the images.
                     In case of a key update, the new record is created but the before image is incomplete.

        arguments:   pOldRec     [in]     pointer to the existing record
                     pNewRec     [out]    pointer to the record space reserved to build the new record
                     NewRecSize  [in]     size of the record space
                     BeforeImage [in out] 
                     Error       [out]
    */
    void CreateNewRecordAndBeforeImage (
        const tgg00_Rec     *pOldRec,
        tgg00_Rec           *pNewRec,
        SAPDB_Int4           NewRecSize,
        Log_RecordColumnMap &BeforeImage,
        tgg00_BasisError    &Error);

    //--------------------------------------------------------------Log_RecordColumnMap---
    /*! function:     GetNullValLen
    
        return value: the length for the NULL-values not existing in record
    */
    SAPDB_UInt2 GetNullValLen () const
    {
        return (this->m_PseudoNullValLen);
    }

    //--------------------------------------------------------------Log_RecordColumnMap---
    /*! function:     GetPersistentColumnMapLength
    
        return value: the length of all valid stack entries of the inv description map
    */
    SAPDB_UInt GetPersistentColumnMapLength () const
    {
        return ( m_EntryHeader.ImageLen );
    }

    //--------------------------------------------------------------Log_RecordColumnMap---
    /*! function:    ReadColumnMapPersistent

        description: reads the stack entries from the specified space

        arguments:   ImageReader [in out]
                     IsOk        [out]
    */
    void ReadColumnMapPersistent (
        Log_ActionImageReader &ImageReader,
        SAPDB_Int4             PersistentLen,
        bool                  &IsOk);

    //--------------------------------------------------------------Log_RecordColumnMap---
    /*! function:    WriteColumnMapPersistent

        description: writes the valid stack entries into the before or after image

        arguments:   ImageWriter [in out]
                     IsOk        [out]
    */
    void WriteColumnMapPersistent (
        Log_ActionImageWriter &ImageWriter,
        bool                  &IsOk)       const;

public:
    
    //--------------------------------------------------------------Log_RecordColumnMap---
    /*! function:    AllocateColumnMap
    
        description: allocates all column entries for further calls of InsertColumn
        
        arguments:   RawAllocator [ref]
                     MaxEntries   [in]
                     IsOk         [out]
    */
    void AllocateColumnMap (
        SAPDBMem_IRawAllocator &RawAllocator,
        SAPDB_Int4              MaxEntries,
        bool                   &IsOk);

    //--------------------------------------------------------------Log_RecordColumnMap---
    /*! function:    ExistsEntry

        return result: true, if the entry exists in the record column map

        arguments:   StackEntry [in]
    */
    virtual bool ExistsEntry (const tgg00_StackEntry &StackEntry) const;
        
    //--------------------------------------------------------------Log_RecordColumnMap---
    /*! function:    InsertColumn
    
        description: inserts a column description with its value

        arguments:   StackEntry  [in]  description of the record column
                     pValue      [in]  pointer to the value
                     ValueLength [in]  the length of the value
                     Error       [out]
    */
    void InsertColumn (
        const tgg00_StackEntry &StackEntry,
        const SAPDB_Byte       *pValue,
        SAPDB_Int4              ValueLength,
        tgg00_BasisError       &Error);

    //--------------------------------------------------------------Log_RecordColumnMap---
    /*! function:    WriteToTrace
    */
    virtual void WriteToTrace(const char *title = NULL) const
    {
        Kernel_VTrace trace;
        if ( title != NULL )
            trace << title << FlushLine;
        m_EntryHeader.WriteToTrace("m_EntryHeader:");
        m_ColList [Log_FixKeyColumn].WriteToTrace();
        m_ColList [Log_VarKeyColumn].WriteToTrace();
        m_ColList [Log_FixColumn   ].WriteToTrace();
        m_ColList [Log_VarColumn   ].WriteToTrace();
        trace << "m_AllocatedEntries: "   << m_AllocatedEntries
              << ", m_UsedEntries: "      << m_UsedEntries
              << ", m_PseudoNullValLen: " << m_PseudoNullValLen
              << FlushLine;
    }
        
};
/*! endclass: Log_RecordColumnMap */


#endif  /* LOG_RECORD_COLUMN_MAP_H */
