/****************************************************************************
  module      : vkb54
  author      : JuergenA
  responsible : UweH
  special area: SQL locks
  see also    :
  description : temp logging
 .nf

    ========== licence begin  GPL
    Copyright (c) 2001-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
.fo

 
*****************************************************************************/
 
.tt 1 $SAP$LiveCache$VKB54$
.tt 3 $$KB_temp_logging$1999-03-30$
 
Module  : KB_temp_logging
 
Define  :
 
        PROCEDURE
              k54commit_temp (VAR t : tgg00_TransContext);
 
        PROCEDURE
              k54create_drop_temp_file (
                    VAR t            : tgg00_TransContext;
                    create_drop_type : tgg00_MessType;
                    VAR temp_file    : tgg00_FileId);
 
        PROCEDURE
              k54del_ins_templog (
                    VAR t         : tgg00_TransContext;
                    ins_del_type  : tgg00_MessType;
                    VAR temp_file : tgg00_FileId;
                    VAR rec       : tgg00_Rec);
 
        PROCEDURE
              k54rollback_temp (
                    VAR t      : tgg00_TransContext;
                    rollb_type : tgg00_MessType2);
 
        PROCEDURE
              k54upd_templog (
                    VAR t           : tgg00_TransContext;
                    VAR temp_file   : tgg00_FileId;
                    VAR old_rec     : tgg00_Rec;
                    VAR new_rec     : tgg00_Rec);
 
.CM *-END-* define --------------------------------------
.sp;.cp 3
Use     :
 
        FROM
              KB_trans_state : VKB50;
 
        PROCEDURE
              k50aux_fn_no (
                    transindex          : tgg00_TransIndex;
                    is_perm             : boolean;
                    VAR auxiliary_fn_no : tsp00_Int4);
 
        PROCEDURE
              k50get_temp_log (
                    transindex            : tgg00_TransIndex;
                    VAR logfile_root      : tsp00_PageNo;
                    VAR logcnt            : tsp00_Int4;
                    VAR funct_rollb       : tsp00_Int4;
                    VAR aux_file_exists   : boolean);
 
        PROCEDURE
              k50put_temp_log (
                    transindex      : tgg00_TransIndex;
                    VAR trans_state : tgg00_TransState;
                    logfile_root    : tsp00_PageNo;
                    logcnt          : tsp00_Int4;
                    aux_file_exists : boolean);
 
      ------------------------------ 
 
        FROM
              KB_file_table_handling : VKB64;
 
        PROCEDURE
              k64build_aux_fn_prefix (
                    VAR transid    : tgg91_TransNo;
                    is_perm        : boolean;
                    VAR aux_id     : tgg00_FileId;
                    VAR prefix_len : integer);
 
      ------------------------------ 
 
        FROM
              filesysteminterface_1 : VBD01;
 
        VAR
              b01niltree_id : tgg00_FileId;
 
        PROCEDURE
              b01destroy_file (
                    VAR t            : tgg00_TransContext;
                    VAR file_id      : tgg00_FileId);
 
        PROCEDURE
              b01prefix_destroy_files (
                    VAR t      : tgg00_TransContext;
                    VAR prefix : tgg00_Filename;
                    prefix_len : integer);
 
        PROCEDURE
              b01rename_file (
                    VAR t           : tgg00_TransContext;
                    VAR old_id      : tgg00_FileId;
                    VAR new_id      : tgg00_FileId);
 
        PROCEDURE
              b01tcreate_file (
                    VAR t            : tgg00_TransContext;
                    VAR file_id      : tgg00_FileId);
 
      ------------------------------ 
 
        FROM
              filesysteminterface_2 : VBD02;
 
        PROCEDURE
              b02get_record (
                    VAR t          : tgg00_TransContext;
                    VAR file_id    : tgg00_FileId;
                    VAR rk         : tgg00_Lkey;
                    VAR b          : tgg00_Rec);
 
        PROCEDURE
              b02prev_record (
                    VAR t           : tgg00_TransContext;
                    VAR file_id     : tgg00_FileId;
                    VAR rk          : tgg00_Lkey;
                    inclusive       : boolean;
                    VAR b           : tgg00_Rec);
 
      ------------------------------ 
 
        FROM
              filesysteminterface_7 : VBD07;
 
        PROCEDURE
              b07cadd_record (
                    VAR t           : tgg00_TransContext;
                    VAR file_id     : tgg00_FileId;
                    VAR b           : tgg00_Rec);
 
        PROCEDURE
              b07cdel_record (
                    VAR t           : tgg00_TransContext;
                    VAR file_id     : tgg00_FileId;
                    VAR rk          : tgg00_Lkey);
 
        PROCEDURE
              b07crepl_record (
                    VAR t            : tgg00_TransContext;
                    VAR file_id      : tgg00_FileId;
                    VAR b            : tgg00_Rec);
 
      ------------------------------ 
 
        FROM
              Configuration_Parameter : VGG01;
 
        VAR
              g01code : tgg04_CodeGlobals;
 
      ------------------------------ 
 
        FROM
              GG_cpp_auxiliary_functions : VGG06;
 
        FUNCTION
              gg06IsGreaterOrEqualUint4 (
                    Left  : tsp00_Uint4;
                    Right : tsp00_Uint4) : boolean;
 
      ------------------------------ 
 
        FROM
              Kernel_move_and_fill : VGG101;
 
        PROCEDURE
              SAPDB_PascalMove (
                    mod_id      : tsp00_C6;
                    mod_num     : tsp00_Int4;
                    source_upb  : tsp00_Int4;
                    dest_upb    : tsp00_Int4;
                    source      : tsp00_MoveObjPtr;
                    src_pos     : tsp00_Int4;
                    destin      : tsp00_MoveObjPtr;
                    dest_pos    : tsp00_Int4;
                    length      : tsp00_Int4;
                    VAR err     : tgg00_BasisError);
 
        PROCEDURE
              g10mv (
                    mod_id      : tsp00_C6;            
                    mod_num     : tsp00_Int4;
                    source_upb  : tsp00_Int4;          
                    dest_upb    : tsp00_Int4;
                    source      : tsp00_MoveObjPtr;       
                    src_pos     : tsp00_Int4;
                    destin      : tsp00_MoveObjPtr;       
                    dest_pos    : tsp00_Int4;
                    length      : tsp00_Int4;
                    VAR e       : tgg00_BasisError);
 
      ------------------------------ 
 
        FROM
              RTE-Extension-20 : VSP20;
 
        PROCEDURE
              s20ch4sw (
                    val        : tsp00_Int4;
                    sourceswap : tsp00_SwapKind;
                    VAR dest   : tsp00_C4;
                    di         : tsp00_Int4;
                    destswap   : tsp00_SwapKind);
 
        FUNCTION
              s20or4sw (
                    VAR source     : tsp00_C4;
                    si             : tsp00_Int4;
                    sourceswap     : tsp00_SwapKind;
                    destswap       : tsp00_SwapKind) : tsp00_Int4;
&       ifdef TRACE
 
      ------------------------------ 
 
        FROM
              Test_Procedures : VTA01;
 
        PROCEDURE
              t01buf (
                    debug    : tgg00_Debug;
                    VAR buf  : tsp00_Buf;
                    startpos : integer;
                    endpos   : integer);
 
        PROCEDURE
              t01int4 (
                    debug    : tgg00_Debug;
                    nam      : tsp00_Sname;
                    int      : tsp00_Int4);
 
        PROCEDURE
              t01messtype (
                    debug        : tgg00_Debug;
                    nam          : tsp00_Sname;
                    mess2_type   : tgg00_MessType);
 
        PROCEDURE
              t01mess2type (
                    debug         : tgg00_Debug;
                    nam           : tsp00_Sname;
                    mess2_type    : tgg00_MessType2);
 
        PROCEDURE
              t01msgcheck (
                    msg             : tsp00_C30;
                    check_condition : boolean;
                    bad_int         : tsp00_Int4);
 
        PROCEDURE
              t01p2int4 (
                    debug : tgg00_Debug;
                    nam_1 : tsp00_Sname;
                    int_1 : tsp00_Int4;
                    nam_2 : tsp00_Sname;
                    int_2 : tsp00_Int4);
&       endif
 
.CM *-END-* use -----------------------------------------
.sp;.cp 3
Synonym :
 
        PROCEDURE
              s20ch4sw;
 
              tsp00_MoveObj tsp00_C4
 
        PROCEDURE
              s20or4sw;
 
              tsp00_MoveObj tsp00_C4
 
.CM *-END-* synonym -------------------------------------
.sp;.cp 3
Author  : JuergenA
.sp
.cp 3
Created : 1991-04-15
.sp
.cp 3
.sp
.cp 3
Release :      Date : 1999-03-30
.sp
***********************************************************
.sp
.cp 10
.fo
.oc _/1
Specification:
.sp
Review: 1995-09-21
.sp 2
.cp 4;.nf
Procedure K54CREATE_DROP_TEMP_FILE
.sp
CREATE_DROP_TYPE      create temp file : m_create_table
                      drop temp file   : m_drop
.fo
.sp 2;.cp 4;.nf
Procedure K54DEL_INS_TEMPLOG
.sp
INS_DEL_TYPE          m_delete
                      m_insert
.fo
.sp 2;.cp 6;.nf
Procedure K54TEMP_ROLLBACK
.sp
ROLLB_TYPE      normal   rollback : mm_rollback
                function rollback : mm_nil
                rollback subtrans : mm_subtrans
.fo
.CM *-END-* specification -------------------------------
.sp 2
************************************************************
.sp
.cp 10
.fo
.oc _/1
Description:
.sp
.CM *-END-* description ---------------------------------
.sp 2
**********************************************************
.sp
.cp 10
.nf
.oc _/1
Structure:
 
.CM *-END-* structure -----------------------------------
.sp 2
**********************************************************
.sp
.cp 10
.nf
.oc _/1
.CM -lll-
Code    :
 
 
CONST
      mx_logkey         =  4;
      mx_temp_logheader = 40;
      c_aux_file_exists = true;
      c_inclusive       = true;
      c_perm            = true;
 
TYPE
 
      t_logrec = RECORD
            CASE integer OF
                1:
                    (rec : tgg00_Rec);
                2:
                    (lgr_len_space    : tsp00_C4;
                    lgr_varcol_offset : tsp00_Int2;
                    lgr_varcol_cnt    : tsp00_Int2;
                    (* *)
                    lgr_key           : tsp00_C4;
                    lgr_logtype       : tgg00_MessType;
                    lgr_logtype2      : tgg00_MessType2;
                    lgr_fill0         : tsp00_Int2;         (* PTS 1109485 E.Z. *)
                    (* *)
                    lgr_subtrans      : tgg00_SubtransNo;   (* PTS 1109485 E.Z. *)
                    lgr_fn            : tgg00_Filename;
                    lgr_filetype      : tgg00_FiletypeSet;
                    lgr_fill1         : boolean;
                    lgr_fill2         : tsp00_Int2;
                    (*                                24 bytes *)
                    lgr_rec_len       : tsp00_Int2;
                    lgr_rec_keylen    : tsp00_Int2);
                3:
                    (lgr_space1      : tsp00_C20;
                    lgr_space2       : tgg00_Filename;
                    lgr_aux_fn       : tgg00_Filename;
                    lgr_aux_filetype : tgg00_FiletypeSet);
                END;
            (*ENDCASE*) 
 
 
 
(*------------------------------*) 
 
PROCEDURE
      k54commit_temp (VAR t : tgg00_TransContext);
 
VAR
      aux_file_exists : boolean;
      prefix_len      : integer;
      dummy_rollb     : tsp00_Int4;
      last_logcnt     : tsp00_Int4;
      root_logfile    : tsp00_Int4;
      aux_id          : tgg00_FileId;
      logfile         : tgg00_FileId;
 
BEGIN
t.trError_gg00 := e_ok;
IF  t.trIndex_gg00 = cgg_nil_transindex
THEN
    t.trError_gg00 := e_nil_transindex;
(*ENDIF*) 
IF  (t.trError_gg00 = e_ok) AND (t.trIndex_gg00 <> cgg_nil_transindex)
THEN
    k50get_temp_log (t.trIndex_gg00, root_logfile, last_logcnt, dummy_rollb,
          aux_file_exists)
ELSE
    last_logcnt := 0;
(*ENDIF*) 
IF  last_logcnt > 0
THEN
    BEGIN
    IF  aux_file_exists
    THEN
        BEGIN
        k64build_aux_fn_prefix (t.trTransId_gg00, NOT c_perm, aux_id, prefix_len);
        b01prefix_destroy_files (t, aux_id.fileName_gg00, prefix_len);
        IF  t.trError_gg00 = e_file_not_found
        THEN
            t.trError_gg00 := e_ok
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    IF  t.trError_gg00 = e_ok
    THEN
        BEGIN
        kb54build_logfile_id (t.trTransId_gg00, logfile);
        logfile.fileRoot_gg00 := root_logfile;
        b01destroy_file (t, logfile);
        IF  t.trError_gg00 = e_file_not_found
        THEN
            t.trError_gg00 := e_ok;
        (*ENDIF*) 
        k50put_temp_log (t.trIndex_gg00, t.trState_gg00,
              NIL_PAGE_NO_GG00, 0, NOT c_aux_file_exists);
        IF  tsTempUpdated_egg00 in t.trState_gg00
        THEN
            t.trState_gg00 := t.trState_gg00 - [tsTempUpdated_egg00]
        (*ENDIF*) 
        END
    (*ENDIF*) 
    END
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      k54create_drop_temp_file (
            VAR t            : tgg00_TransContext;
            create_drop_type : tgg00_MessType;
            VAR temp_file    : tgg00_FileId);
 
VAR
      entry_len : integer;
      dummy_len : integer;
      aux_file  : tgg00_FileId;
      logfile   : tgg00_FileId;
      logrec    : t_logrec;
 
BEGIN
t.trError_gg00 := e_ok;
&ifdef TRACE
t01msgcheck ('K54CREATE_DROP: wrong messtype',
      (create_drop_type = m_create_table) OR
      (create_drop_type = m_drop), ord (create_drop_type));
&endif
IF  hsNoLog_egg00 in temp_file.fileHandling_gg00
THEN
    BEGIN
    IF  t.trIndex_gg00 = cgg_nil_transindex
    THEN
        t.trError_gg00 := e_nil_transindex;
    (*ENDIF*) 
    END
ELSE
    BEGIN
    IF  create_drop_type = m_create_table
    THEN
        entry_len := mx_temp_logheader
    ELSE
        entry_len := mx_temp_logheader + FN_MXGG00 + 1;
    (*ENDIF*) 
    kb54init_logentry (t, temp_file, create_drop_type, mm_nil,
          entry_len, logrec, logfile)
    END;
(*ENDIF*) 
IF  (t.trError_gg00 = e_ok) AND (create_drop_type = m_create_table)
THEN
    b01tcreate_file (t, temp_file);
(*ENDIF*) 
IF  (t.trError_gg00 = e_ok) AND (create_drop_type = m_drop)
THEN
    BEGIN
    IF  hsNoLog_egg00 in temp_file.fileHandling_gg00
    THEN
        b01destroy_file (t, temp_file)
    ELSE
        BEGIN
        k64build_aux_fn_prefix (t.trTransId_gg00, NOT c_perm, aux_file, dummy_len);
        aux_file.fileType_gg00 := temp_file.fileType_gg00;
        k50aux_fn_no (t.trIndex_gg00, NOT c_perm, aux_file.fileAuxCnt_gg00);
        b01rename_file (t, temp_file, aux_file);
        logrec.lgr_aux_fn       := aux_file.fileName_gg00;
        logrec.lgr_aux_filetype := aux_file.fileType_gg00
        END
    (*ENDIF*) 
    END;
(*ENDIF*) 
IF  (t.trError_gg00 = e_ok)
    AND NOT (hsNoLog_egg00 in temp_file.fileHandling_gg00)
THEN
    b07cadd_record (t, logfile, logrec.rec);
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      k54del_ins_templog (
            VAR t         : tgg00_TransContext;
            ins_del_type  : tgg00_MessType;
            VAR temp_file : tgg00_FileId;
            VAR rec       : tgg00_Rec);
 
VAR
      logtype2    : tgg00_MessType2;
      move_len    : integer;
      logdata_len : integer;
      logfile     : tgg00_FileId;
      logrec      : t_logrec;
 
BEGIN
t.trError_gg00 := e_ok;
&ifdef TRACE
t01msgcheck ('K54DEL_INS: wrong messtype    ',
      (ins_del_type = m_insert) OR
      (ins_del_type = m_delete), ord (ins_del_type));
&endif
IF  ins_del_type = m_insert
THEN
    logdata_len := cgg_rec_key_offset + rec.keylen
ELSE
    logdata_len := rec.len;
(*ENDIF*) 
WHILE (t.trError_gg00 = e_ok) AND (logdata_len > 0) DO
    BEGIN
    IF  mx_temp_logheader + logdata_len > MAX_RECLEN_GG00
    THEN
        BEGIN
        logtype2 := mm_last;
        move_len := mx_temp_logheader + logdata_len - MAX_RECLEN_GG00
        END
    ELSE
        BEGIN
        logtype2 := mm_first;
        move_len := logdata_len
        END;
    (*ENDIF*) 
    logdata_len := logdata_len - move_len;
    kb54init_logentry (t, temp_file, ins_del_type, logtype2,
          mx_temp_logheader + move_len, logrec, logfile);
    IF  t.trError_gg00 = e_ok
    THEN
        g10mv ('VKB54 ',   1,
              sizeof (rec.buf), sizeof (logrec.rec.buf),
              @rec.buf, logdata_len + 1,
              @logrec.rec.buf, mx_temp_logheader + 1, move_len,
              t.trError_gg00);
    (*ENDIF*) 
    IF  t.trError_gg00 = e_ok
    THEN
        b07cadd_record (t, logfile, logrec.rec)
    (*ENDIF*) 
    END
(*ENDWHILE*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      k54rollback_temp (
            VAR t      : tgg00_TransContext;
            rollb_type : tgg00_MessType2);
 
VAR
      drop_logfile   : boolean;
      dummy_exists   : boolean;
      read_log       : boolean;
      rec_incomplete : boolean;
      i              : integer;
      move_len       : integer;
      pos            : integer;
      stop_rollb     : tsp00_Int4;
      curr_logcnt    : tsp00_Int4;
      last_logcnt    : tsp00_Int4;
      root_logfile   : tsp00_Int4;
      aux_file       : tgg00_FileId;
      logfile        : tgg00_FileId;
      temp_file      : tgg00_FileId;
      k              : tgg00_Lkey;
      logkey         : tgg00_Lkey;
      logrec         : t_logrec;
      rec            : tgg00_Rec;
 
BEGIN
t.trError_gg00 := e_ok;
&ifdef TRACE
t01mess2type (kb, 'rollb_type  ', rollb_type);
&endif
k50get_temp_log (t.trIndex_gg00, root_logfile, last_logcnt, stop_rollb,
      dummy_exists);
IF  last_logcnt > 0
THEN
    BEGIN
    kb54build_logfile_id (t.trTransId_gg00, logfile);
    logfile.fileRoot_gg00 := root_logfile;
    drop_logfile := (rollb_type = mm_rollback);
    logkey.len   := mx_logkey;
    FOR i := 1 TO mx_logkey DO
        logkey.k [i] := chr(255);
    (*ENDFOR*) 
    read_log   := true;
    t.trState_gg00 := t.trState_gg00 + [tsRollback_egg00];
    REPEAT
        rec_incomplete := false;
        b02prev_record (t,logfile, logkey, NOT c_inclusive, logrec.rec);
        IF  (t.trError_gg00 = e_ok) OR (t.trError_gg00 = e_key_not_found)
        THEN
            t.trError_gg00 := e_ok
        ELSE
            IF  (t.trError_gg00 = e_file_empty    ) OR
                (t.trError_gg00 = e_no_prev_record)
            THEN
                BEGIN
                t.trError_gg00 := e_ok;
                read_log := false;
                b01destroy_file (t, logfile);
                k50put_temp_log (t.trIndex_gg00, t.trState_gg00,
                      NIL_PAGE_NO_GG00, 0, NOT c_aux_file_exists);
                IF  tsTempUpdated_egg00 in t.trState_gg00
                THEN
                    t.trState_gg00 := t.trState_gg00 - [tsTempUpdated_egg00]
                (*ENDIF*) 
                END
            ELSE
                IF  t.trError_gg00 = e_file_not_found
                THEN
                    BEGIN
                    t.trError_gg00 := e_ok;
                    read_log := false
                    END;
                (*ENDIF*) 
            (*ENDIF*) 
        (*ENDIF*) 
        ;
&       ifdef TRACE
        IF  (t.trError_gg00 = e_ok) AND read_log
        THEN
            BEGIN
            t01messtype  (kb, 'logtype     ', logrec.lgr_logtype );
            t01mess2type (kb, 'logtype2    ', logrec.lgr_logtype2)
            END;
&       endif
        (*ENDIF*) 
        IF  (t.trError_gg00 = e_ok) AND read_log AND (rollb_type = mm_nil)
        THEN
            (* function rollback *)
            BEGIN
            curr_logcnt := s20or4sw (logrec.lgr_key, 1,
                  sw_normal, g01code.kernel_swap);
            read_log := (curr_logcnt > stop_rollb)
            END;
        (*ENDIF*) 
        IF  (t.trError_gg00 = e_ok) AND read_log AND
            (rollb_type = mm_subtrans)
        THEN
            read_log := gg06IsGreaterOrEqualUint4
                  (logrec.lgr_subtrans, t.trSubtransId_gg00);
        (*ENDIF*) 
        IF  (t.trError_gg00 = e_ok)
            AND read_log
            AND (logrec.lgr_logtype in [m_delete, m_update])
            AND (logrec.lgr_logtype2 <> mm_optimize)
        THEN
            BEGIN
            IF  logrec.lgr_logtype2 = mm_first
            THEN
                pos := 1;
            (*ENDIF*) 
            move_len := logrec.rec.len - mx_temp_logheader;
            g10mv ('VKB54 ',   2,
                  sizeof (logrec.rec.buf), sizeof (rec.buf),
                  @logrec.rec.buf, mx_temp_logheader + 1,
                  @rec.buf, pos, move_len, t.trError_gg00);
            pos := pos + move_len;
            rec_incomplete := (pos <= rec.len)
            END;
        (*ENDIF*) 
        IF  (t.trError_gg00 = e_ok)
            AND read_log
            AND NOT rec_incomplete
        THEN
            BEGIN
            temp_file               := b01niltree_id;
            temp_file.fileType_gg00 := logrec.lgr_filetype;
            temp_file.fileName_gg00 := logrec.lgr_fn;
            CASE logrec.lgr_logtype OF
                m_create_table:
                    BEGIN
                    b01destroy_file (t, temp_file);
                    IF  t.trError_gg00 = e_file_not_found
                    THEN
                        t.trError_gg00 := e_ok
                    (*ENDIF*) 
                    END;
                m_delete:
                    BEGIN
                    b07cadd_record (t, temp_file, rec);
                    IF  (t.trError_gg00 = e_file_not_found) OR
                        (t.trError_gg00 = e_duplicate_key )
                    THEN
                        t.trError_gg00 := e_ok
                    (*ENDIF*) 
                    END;
                m_drop:
                    BEGIN
                    aux_file               := b01niltree_id;
                    aux_file.fileType_gg00 := logrec.lgr_aux_filetype;
                    aux_file.fileName_gg00 := logrec.lgr_aux_fn;
                    b01rename_file (t, aux_file, temp_file);
                    IF  t.trError_gg00 = e_file_not_found
                    THEN
                        t.trError_gg00 := e_ok
                    (*ENDIF*) 
                    END;
                m_insert:
                    BEGIN
                    k.len := logrec.lgr_rec_keylen;
                    g10mv ('VKB54 ',   3,
                          sizeof (logrec.rec.buf), sizeof (k.k),
                          @logrec.rec.buf,
                          mx_temp_logheader + cgg_rec_key_offset + 1,
                          @k.k, 1, k.len, t.trError_gg00);
                    IF  t.trError_gg00 = e_ok
                    THEN
                        b07cdel_record (t, temp_file, k);
                    (*ENDIF*) 
                    IF  (t.trError_gg00 = e_file_not_found) OR
                        (t.trError_gg00 = e_key_not_found )
                    THEN
                        t.trError_gg00 := e_ok
                    (*ENDIF*) 
                    END;
                m_update:
                    BEGIN
                    IF  logrec.lgr_logtype2 = mm_optimize
                    THEN
                        BEGIN
                        k.len := logrec.lgr_rec_keylen;
                        g10mv ('VKB54 ',   4,
                              sizeof (logrec.rec.buf), sizeof (k.k),
                              @logrec.rec.buf,
                              mx_temp_logheader + cgg_rec_key_offset +1,
                              @k.k, 1, k.len, t.trError_gg00);
                        IF  t.trError_gg00 = e_ok
                        THEN
                            b02get_record (t, temp_file, k, rec);
                        (*ENDIF*) 
                        IF  t.trError_gg00 = e_ok
                        THEN
                            BEGIN
                            rec.len := logrec.lgr_rec_len;
                            pos     := mx_temp_logheader
                                  + cgg_rec_key_offset + k.len + 1;
                            WHILE pos+RECPART_MXGG00 <= logrec.rec.len DO
                                BEGIN
                                g10mv ('VKB54 ',   5,
                                      sizeof (logrec.rec.buf),
                                      sizeof (tgg00_RecPart),
                                      @logrec.rec.buf, pos + 1,
                                      @rec.recpart
                                      [ord (logrec.rec.buf [pos])], 1,
                                      sizeof (tgg00_RecPart), t.trError_gg00);
                                pos := pos + 1 + RECPART_MXGG00
                                END
                            (*ENDWHILE*) 
                            END
                        (*ENDIF*) 
                        END;
                    (*ENDIF*) 
                    IF  t.trError_gg00 = e_ok
                    THEN
                        b07crepl_record (t, temp_file, rec);
                    (*ENDIF*) 
                    IF  (t.trError_gg00 = e_file_not_found) OR
                        (t.trError_gg00 = e_key_not_found )
                    THEN
                        t.trError_gg00 := e_ok
                    (*ENDIF*) 
                    END
                END
            (*ENDCASE*) 
            END;
        (*ENDIF*) 
        IF  (t.trError_gg00 = e_ok) AND read_log
        THEN
            BEGIN
            logkey.len := mx_logkey;
            FOR i := 1 TO mx_logkey DO
                logkey.k [i] := logrec.lgr_key [i];
            (*ENDFOR*) 
            IF  rollb_type <> mm_rollback
            THEN
                b07cdel_record (t, logfile, logkey)
            (*ENDIF*) 
            END
        (*ENDIF*) 
    UNTIL
        NOT read_log OR (t.trError_gg00 <> e_ok);
    (*ENDREPEAT*) 
    t.trState_gg00 := t.trState_gg00 - [tsRollback_egg00]
    END
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      k54upd_templog (
            VAR t           : tgg00_TransContext;
            VAR temp_file   : tgg00_FileId;
            VAR old_rec     : tgg00_Rec;
            VAR new_rec     : tgg00_Rec);
 
CONST
      min_optimize_len = 1024;
      min_optimize_dif =  512;
 
VAR
      logtype2     : tgg00_MessType2;
      i            : integer;
      len_new_rec  : integer;
      logdata_len  : integer;
      min_part_cnt : integer;
      min_rec_len  : integer;
      move_len     : integer;
      new_part_cnt : integer;
      old_part_cnt : integer;
      pos          : integer;
      upd_cnt      : integer;
      logfile      : tgg00_FileId;
      is_upd       : ARRAY [0..MAX_RECPARTS_GG00] OF boolean;
      logrec       : t_logrec;
 
BEGIN
t.trError_gg00 := e_ok;
logtype2 := mm_nil;
IF  old_rec.len >= min_optimize_len
THEN
    BEGIN
&   ifdef TRACE
    t01int4 (kb, 'old_record  ',  old_rec.len);
    t01buf  (kb,  old_rec.buf, 1, old_rec.len);
    t01int4 (kb, 'new_record  ',  new_rec.len);
    t01buf  (kb,  new_rec.buf, 1, new_rec.len);
&   endif
    old_part_cnt:= (old_rec.len + RECPART_MXGG00 -1) DIV RECPART_MXGG00 - 1;
    new_part_cnt:= (new_rec.len + RECPART_MXGG00 -1) DIV RECPART_MXGG00 - 1;
    IF  old_rec.len < new_rec.len
    THEN
        BEGIN
        min_rec_len  := old_rec.len;
        min_part_cnt := old_part_cnt
        END
    ELSE
        BEGIN
        min_rec_len  := new_rec.len;
        min_part_cnt := new_part_cnt
        END;
    (*ENDIF*) 
&   ifdef TRACE
    t01p2int4 (kb, 'min_rec_len ', min_rec_len
          ,        'min_part_cnt', min_part_cnt);
    t01p2int4 (kb, 'old_part_cnt', old_part_cnt
          ,        'new_part_cnt', new_part_cnt);
&   endif
    len_new_rec := new_rec.len;
    new_rec.len := old_rec.len;
    upd_cnt     := 0;
    FOR i := 0 TO min_part_cnt-1 DO
        IF  old_rec.recpart [i] = new_rec.recpart [i]
        THEN
            is_upd [i] := false
        ELSE
            BEGIN
            is_upd [i] := true;
            upd_cnt    := upd_cnt + 1
            END;
        (*ENDIF*) 
    (*ENDFOR*) 
    IF  (min_rec_len MOD RECPART_MXGG00 = 0)
        AND
        ( old_rec.recpart [min_part_cnt]
        = new_rec.recpart [min_part_cnt])
    THEN
        is_upd [min_part_cnt] := false
    ELSE
        IF  old_rec.len <> len_new_rec
        THEN
            BEGIN
            is_upd [min_part_cnt] := true;
            upd_cnt := upd_cnt + 1
            END
        ELSE
            BEGIN
            i := min_part_cnt * RECPART_MXGG00 + 1;
            is_upd [min_part_cnt] := false;
            WHILE NOT is_upd [min_part_cnt] AND (i <= min_rec_len) DO
                IF  old_rec.buf [i] = new_rec.buf [i]
                THEN
                    i := i + 1
                ELSE
                    BEGIN
                    is_upd [min_part_cnt] := true;
                    upd_cnt := upd_cnt + 1
                    END
                (*ENDIF*) 
            (*ENDWHILE*) 
            END;
        (*ENDIF*) 
    (*ENDIF*) 
    new_rec.len := len_new_rec;
    i := min_part_cnt + 1;
    WHILE i <= old_part_cnt DO
        BEGIN
        is_upd [i] := true;
        upd_cnt    := upd_cnt + 1;
        i := i + 1
        END;
    (*ENDWHILE*) 
    logdata_len := cgg_rec_key_offset + old_rec.keylen
          + upd_cnt * (1 + RECPART_MXGG00);
    IF  ((old_rec.len - logdata_len >= min_optimize_dif) OR
        ( mx_temp_logheader + old_rec.len > MAX_RECLEN_GG00))
        AND
        (mx_temp_logheader + logdata_len <= MAX_RECLEN_GG00)
    THEN
        logtype2 := mm_optimize
    (*ENDIF*) 
    END;
(*ENDIF*) 
IF  logtype2 <> mm_optimize
THEN
    logdata_len := old_rec.len;
&ifdef TRACE
(*ENDIF*) 
t01int4 (kb, 'logdata_len ', logdata_len);
&endif
WHILE (t.trError_gg00 = e_ok) AND (logdata_len > 0) DO
    BEGIN
    IF  logtype2 = mm_optimize
    THEN
        move_len := logdata_len
    ELSE
        IF  mx_temp_logheader + logdata_len > MAX_RECLEN_GG00
        THEN
            BEGIN
            logtype2 := mm_next;
            move_len := mx_temp_logheader + logdata_len - MAX_RECLEN_GG00
            END
        ELSE
            BEGIN
            logtype2 := mm_first;
            move_len := logdata_len
            END;
        (*ENDIF*) 
    (*ENDIF*) 
    logdata_len := logdata_len - move_len;
    kb54init_logentry (t, temp_file, m_update, logtype2,
          mx_temp_logheader + move_len, logrec, logfile);
&   ifdef TRACE
    t01p2int4    (kb, 'move_len    ', move_len
          ,           'logdata_len ', logdata_len);
    t01mess2type (kb, 'logtype2    ', logtype2);
&   endif
    IF  t.trError_gg00 = e_ok
    THEN
        BEGIN
        IF  logtype2 = mm_optimize
        THEN
            BEGIN
            pos := mx_temp_logheader + 1;
            g10mv ('VKB54 ',   6,
                  sizeof (old_rec.buf), sizeof (logrec.rec.buf),
                  @old_rec.buf, 1,
                  @logrec.rec.buf, pos,
                  cgg_rec_key_offset + old_rec.keylen, t.trError_gg00);
            pos := pos + cgg_rec_key_offset + old_rec.keylen;
            FOR i := 0 TO old_part_cnt DO
                IF  is_upd [i]
                THEN
                    BEGIN
&                   ifdef TRACE
                    t01int4 (kb, 'upd recpart ', i);
&                   endif
                    logrec.rec.buf [pos] := chr (i);
                    g10mv ('VKB54 ',   7,
                          sizeof (old_rec.recpart [i]),
                          sizeof (logrec.rec.buf),
                          @old_rec.recpart [i], 1,
                          @logrec.rec.buf, pos + 1,
                          sizeof (old_rec.recpart [i]), t.trError_gg00);
                    pos := pos + 1 + RECPART_MXGG00
                    END
                (*ENDIF*) 
            (*ENDFOR*) 
            END
        ELSE
            g10mv ('VKB54 ',   8,
                  sizeof (old_rec.buf), sizeof (logrec.rec.buf),
                  @old_rec.buf, logdata_len + 1,
                  @logrec.rec.buf, mx_temp_logheader + 1,
                  move_len, t.trError_gg00);
        (*ENDIF*) 
        IF  t.trError_gg00 = e_ok
        THEN
            b07cadd_record (t, logfile, logrec.rec)
        (*ENDIF*) 
        END
    (*ENDIF*) 
    END
(*ENDWHILE*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      kb54build_logfile_id (
            VAR transid : tgg91_TransNo;
            VAR logfile : tgg00_FileId);
 
BEGIN
logfile                  := b01niltree_id;
logfile.fileType_gg00    := [ftsTemp_egg00]; (* not concurrent *)
logfile.fileTfn_gg00     := tfnTempLog_egg00;
logfile.fileTransId_gg00 := transid
END;
 
(*------------------------------*) 
 
PROCEDURE
      kb54init_logentry (
            VAR t         : tgg00_TransContext;
            VAR temp_file : tgg00_FileId;
            logtype       : tgg00_MessType;
            logtype2      : tgg00_MessType2;
            logentry_len  : integer;
            VAR logrec    : t_logrec;
            VAR logfile   : tgg00_FileId);
 
VAR
      aux_file_exists : boolean;
      dummy_rollb     : tsp00_Int4;
      logcnt          : tsp00_Int4;
 
BEGIN
t.trError_gg00 := e_ok;
kb54build_logfile_id (t.trTransId_gg00, logfile);
aux_file_exists := false;
IF  t.trIndex_gg00 <> cgg_nil_transindex
THEN
    k50get_temp_log (t.trIndex_gg00, logfile.fileRoot_gg00, logcnt, dummy_rollb,
          aux_file_exists)
ELSE
    t.trError_gg00 := e_nil_transindex;
(*ENDIF*) 
IF  (t.trError_gg00 = e_ok) AND (logcnt <= 0)
THEN
    BEGIN
    b01tcreate_file (t, logfile);
    IF  NOT (tsTempUpdated_egg00 in t.trState_gg00)
    THEN
        t.trState_gg00 := t.trState_gg00 + [tsTempUpdated_egg00]
    (*ENDIF*) 
    END;
(*ENDIF*) 
IF  t.trError_gg00 = e_ok
THEN
    BEGIN
    logcnt := logcnt + 1;
    k50put_temp_log (t.trIndex_gg00, t.trState_gg00, logfile.fileRoot_gg00, logcnt,
          (aux_file_exists OR (logtype = m_drop)) );
    s20ch4sw (logcnt, g01code.kernel_swap,
          logrec.lgr_key, 1, sw_normal);
    logrec.rec.len           := logentry_len;
    logrec.rec.keylen        := mx_logkey;
    logrec.lgr_varcol_offset := 0;
    logrec.lgr_varcol_cnt    := 0;
    logrec.lgr_logtype       := logtype;
    logrec.lgr_logtype2      := logtype2;
    logrec.lgr_subtrans      := t.trSubtransId_gg00;
    logrec.lgr_fn            := temp_file.fileName_gg00;
    logrec.lgr_filetype      := temp_file.fileType_gg00;
    logrec.lgr_fill1         := false;
    logrec.lgr_fill2         := 0
    END
(*ENDIF*) 
END;
 
.CM *-END-* code ----------------------------------------
.SP 2 
***********************************************************
.PA 
