blob: c92dd22d228b8508d0223d3328c3fee51cc5231c [file] [log] [blame]
/**********************************************************************
// @@@ START COPYRIGHT @@@
//
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
//
// @@@ END COPYRIGHT @@@
//
**********************************************************************/
#ifndef _RU_TBL_H_
#define _RU_TBL_H_
/* -*-C++-*-
******************************************************************************
*
* File: RUTbl.h
* Description: Definition of class CRUTbl
*
* Created: 02/27/2000
* Language: C++
*
*
******************************************************************************
*/
#include "refresh.h"
#include "dsplatform.h"
#include "ddTblUsedByMV.h"
#include "RuObject.h"
#include "RuDeltaDef.h"
class CDDTable;
class CDDColumnList;
class CDDKeyColumnList;
class CRUMV;
class CRUMVList;
class CRUKeyColumnList;
class CUOFsFileList;
class CDSStringList;
class CRUEmpCheckVector;
//--------------------------------------------------------------------------//
// CRUTbl (inherits from CRUObject)
//
// CRUTbl is a wrapper class for CDDTblUsedByMV that reflects
// the properties of a table being used by MV in a particular
// invocation of REFRESH. These properties can follow either
// from the metadata (e.g., what is the table's current epoch?),
// or from the utility logic (e.g., should this table be read-locked
// throughout this invocation to achieve consistency?)
//
// The class provides the functionality of updating the metadata
// and saving it in the SMD and UMD tables, acquiring and releasing
// resources etc.
//
// The class is an *abstract* class. Several methods depend on the
// table's implementation (is it a regular table or an MV itself?).
// The concrete implementations are in RuTblImpl[.h/.cpp]
//
// The class maintains the following "core" pointers/objects:
// (1) The pointer to the core DDOL object, pddTblUsedByMV_.
//
// (2) The list of pointers to the CRUMV objects for the involved MVs
// *directly* using the table (that do not specify it as IGNORE
// CHANGES), pMVsUsingMe_. This list does not own the referenced
// objects, and hence does not deallocate them in its destructor.
//
// (3) The pointer to the CRUMV object (MV interface), if the table is
// also an involved MV - pMVInterface_.
//
// (4) The pointer to the DDOL object for the IUD log table, pddIUDLogTbl_.
// The operations on the log (i.e., read-protected open) are done
// by the utility through the CRUTbl object.
//
// There are four auxiliary "using MVs lists" that are maintained.
// All of them are a subset of pMVsUsingMe_ (self-commenting):
// (1) pOnRequestMVsUsingMe_
// (2) pInvolvedMVsUsingMe_
// (3) pOnRequestInvolvedMVsUsingMe_
// (4) pIncInvolvedMVsUsingMe_ - the involved ON REQUEST MVs that will
// NOT be recomputed by this invocation of Refresh.
//
// Various tasks of the Refresh utility use the class to exchange data
// the task's execution has computed in (for example, the DE statistics).
// This allows a flexible design of the dependence graph, where various
// tasks need not know the entire graph's connectivity to exchange data.
// They just find it at the CRUTbl object.
//
//--------------------------------------------------------------------------//
class REFRESH_LIB_CLASS CRUTbl : public CRUObject {
private:
typedef CRUObject inherited;
public:
CRUTbl(CDDTblUsedByMV *pddTblUsedByMV);
virtual ~CRUTbl();
//--------------------------------//
// Accessors
//--------------------------------//
public:
// Main usage list
CRUMVList &GetMVsUsingMe() const
{
RUASSERT(NULL != pMVsUsingMe_);
return *pMVsUsingMe_;
}
// Auxiliary usage lists
CRUMVList &GetOnRequestMVsUsingMe() const
{
RUASSERT(NULL != pOnRequestMVsUsingMe_);
return *pOnRequestMVsUsingMe_;
}
CRUMVList &GetInvolvedMVsUsingMe() const
{
RUASSERT(NULL != pInvolvedMVsUsingMe_);
return *pInvolvedMVsUsingMe_;
}
CRUMVList &GetOnRequestInvolvedMVsUsingMe() const
{
RUASSERT(NULL != pOnRequestInvolvedMVsUsingMe_);
return *pOnRequestInvolvedMVsUsingMe_;
}
// GetOnRequestInvolvedMVsUsingMe().GetCount() > 0
BOOL IsUsedByOnRequestMV() const;
CRUMVList &GetIncrementalInvolvedMVsUsingMe() const
{
RUASSERT(NULL != pIncInvolvedMVsUsingMe_);
return *pIncInvolvedMVsUsingMe_;
}
// GetIncrementalInvolvedMVsUsingMe().GetCount() > 0
BOOL IsUsedByIncRefreshedMV() const;
BOOL IsInvolvedMV() const
{
return (NULL != pMVInterface_);
}
CRUMV *GetMVInterface() const
{
return pMVInterface_;
}
public:
// Pure virtuals - delegated to the derived classes.
virtual BOOL IsRegularTable() const = 0;
// If a used object is regular table, it is always initialized
virtual BOOL IsInitialized() = 0;
virtual BOOL IsAudited() = 0;
// Regular tables and ON STATEMENT MVs
// are always synchronized with the database
virtual BOOL IsFullySynchronized() = 0;
// A table is insert-only if it has an INSERTLOG or
// MANUAL RANGELOG attribute.
BOOL IsInsertLog();
// Get the name of the IUD/range log (not FQ)
CDSString GetLogShortName(const CDSString &nmsp);
//-- Access to the data structures
public:
// Get the STORE BY key column list
CRUKeyColumnList &GetKeyColumnList() const
{
RUASSERT (NULL != pKeyColumnList_);
return *pKeyColumnList_;
}
//-- Get the list of all partition names
const CDSStringList &GetPartitionFileNamesList() const
{
RUASSERT (NULL != pPartitionFileNamesList_);
return *pPartitionFileNamesList_;
}
//-- Expose the statistics gathered by DE
CRUDeltaStatisticsMap &GetStatisticsMap()
{
RUASSERT (NULL != pStatMap_);
return *pStatMap_;
}
// Get the emptiness check's results
CRUEmpCheckVector &GetEmpCheckVector()
{
RUASSERT (NULL != pEmpCheckVector_);
return *pEmpCheckVector_;
}
BOOL IsDeltaNonEmpty(TInt32 fromEpoch);
CRUDeltaDef::DELevel GetDELevel() const
{
return deLevel_;
}
Lng32 getNumberOfPartitions();
public:
// Implementation of pure virtual
virtual BOOL HoldsResources() const
{
return (TRUE == IsDDLLockPending()
||
TRUE == IsRPOpenPending()
||
TRUE == IsLogRPOpenPending());
}
TInt64 GetTimestamp() const
{
return timestamp_;
}
BOOL IsRPOpenPending() const
{
return isRPOpenPending_;
}
BOOL IsLogRPOpenPending() const
{
return isLogRPOpenPending_;
}
// What is the size of the @UPDATE_BITMAP column in the log?
Lng32 GetUpdateBitmapSize();
public:
enum IUDLogContentType {
RANGE = 0x1, // Range records
SINGLE_ROW_INSERTS = 0x2, // Single-row insert records
SINGLE_ROW_OTHER = 0x4, // Single-row delete and update records
SINGLE_ROW = SINGLE_ROW_INSERTS | SINGLE_ROW_OTHER // Any Single-row records
};
// Which kind of records can the IUD log hold?
Lng32 GetIUDLogContentTypeBitmap();
// Should the utility perform DE on this table's log?
BOOL IsDENeeded() const
{
return isDENeeded_;
}
BOOL IsUsedByIncrementalMJV() const
{
return isUsedByIncrementalMJV_;
}
BOOL IsUsedOnlyByMultiTxnMvs() const;
// Should the table be locked (by read-protected open)
// throughout the execution?
BOOL IsLongLockNeeded() const
{
return isLongLockNeeded_;
}
// Must the table's delta be empty for consistency reasons?
BOOL IsEmptyDeltaNeeded() const
{
return isEmptyDeltaNeeded_;
}
BOOL IsIncEpochNeeded() const
{
// Epoch increment is required only if there is
// an involved ON REQUEST MV that uses the tabke
// (not necessarily incrementally refreshed).
return IsUsedByOnRequestMV();
}
//-- Accessor wrappers of DDOL methods
public:
virtual TInt64 GetUID() const
{
return pddTblUsedByMV_->GetUID();
}
BOOL IsNoLockOnRefresh()
{
return pddTblUsedByMV_->IsNoLockOnRefresh();
}
CDDObject::ERangeLogType GetRangeLogType()
{
return pddTblUsedByMV_->GetRangeLogType();
}
CDDUIDTripleList &GetUIDsOfAllMVsUsingMe()
{
return pddTblUsedByMV_->GetMVsUsingMe();
}
TInt32 GetCurrentEpoch()
{
return pddTblUsedByMV_->GetCurrentEpoch();
}
TInt32 GetLastDupElimEpoch()
{
return pddTblUsedByMV_->GetLastDupElimEpoch();
}
TInt32 GetRecomputeEpoch()
{
return pddTblUsedByMV_->GetRecomputeEpoch();
}
BOOL IsLastDEComplete()
{
return pddTblUsedByMV_->IsLastDEComplete();
}
// For direct epoch increment (not through DDOL)
CDSString GetIncEpochCatApiText()
{
return pddTblUsedByMV_->GetIncEpochCatApiText();
}
#ifdef _DEBUG
public:
virtual void Dump(CDSString &to, BOOL isExtended=FALSE);
#endif
//--------------------------------//
// Log-related globals
//--------------------------------//
public:
// Prefix to all the control columns in the log
static const CDSString logCrtlColPrefix;
// IUD log namespace prefix
static const CDSString iudNmspPrefix;
// Range log namespace prefix
static const CDSString rngNmspPrefix;
CDSString GetIUDLogFullName(BOOL useNmsp=TRUE)
{
return GetLogFullName(CRUTbl::iudNmspPrefix, useNmsp);
}
CDSString GetRangeLogFullName(BOOL useNmsp=TRUE)
{
return GetLogFullName(CRUTbl::rngNmspPrefix, useNmsp);
}
//--------------------------------//
// Mutators
//--------------------------------//
//--- Connectivity updates
public:
//-- Reference management: update the usage lists
void AddRefToUsingMV(CRUMV *pMV);
void SetMVInterface(CRUMV *pMV)
{
pMVInterface_ = pMV;
}
// Store the pointer to the IUD log table
void FixupIUDLogTbl(CDDTable *pddIUDLogTbl)
{
pddIUDLogTbl_ = pddIUDLogTbl;
}
// Build the list when you know for sure
// which MVs are going to be incrementally refreshed
void BuildListOfIncrementalInvolvedMVsUsingMe();
public:
//-- Implementation of pure virtual
virtual void ReleaseResources();
public:
//-- Build the list of key columns (for the DE purposes)
void BuildKeyColumnList();
//-- Build the list of all partition names
void BuildPartitionFileNamesList();
//-- Build the emptiness check vector
void BuildEmpCheckVector();
void CheckIfLongLockNeeded();
void SetLongLockIsNeeded()
{
isLongLockNeeded_ = TRUE;
}
void CheckIfDENeeded();
virtual void SetTimestamp(TInt64 ts)
{
timestamp_ = ts;
}
void SetEmptyDeltaNeeded()
{
isEmptyDeltaNeeded_ = TRUE;
}
void SetDELevel(CRUDeltaDef::DELevel deLevel)
{
deLevel_ = deLevel;
}
public:
//-- Event propagation to the using MVs
void PropagateEmpCheckToUsingMVs();
void PropagateRecomputeToUsingMVs();
void PropagateDEStatisticsToUsingMVs();
public:
//-- Pure virtuals - to be refined by the derived classes
//-- Read-protected opens for achieving consistency
virtual void ExecuteReadProtectedOpen() = 0;
virtual void ReleaseReadProtectedOpen() = 0;
void ExecuteLogReadProtectedOpen();
void ReleaseLogReadProtectedOpen();
//-- Mutator wrappers
public:
// Fetch the metadata about epochs (not of general use in DDOL).
virtual void FetchMetadata()
{
pddTblUsedByMV_->FetchMVRefreshMetadata();
}
// Flush the metadata changes to the SMD and UMD tables
virtual void SaveMetadata()
{
pddTblUsedByMV_->Save();
}
// Cancel saving the metadata
virtual void CancelChanges()
{
pddTblUsedByMV_->CancelChanges();
}
void IncrementCurrentEpoch(BOOL changeObjectState = TRUE)
{
pddTblUsedByMV_->IncrementCurrentEpoch(changeObjectState);
}
void SetLastDupElimEpoch(TInt32 ep)
{
pddTblUsedByMV_->SetLastDupElimEpoch(ep);
}
void SetRecomputeEpoch(TInt32 ep)
{
pddTblUsedByMV_->SetRecomputeEpoch(ep);
}
void SetMinLogEpoch(TInt32 ep)
{
pddTblUsedByMV_->SetMinLogEpoch(ep);
}
void SetLastDEComplete(BOOL flag)
{
pddTblUsedByMV_->SetLastDEComplete(flag);
}
//-------------------------------------------//
// PROTECTED AREA
//-------------------------------------------//
protected:
//-- Pure virtuals
//-- Retrieve the column and key column lists from DDOL
virtual CDDColumnList *GetDDColumnList() = 0;
virtual CDDKeyColumnList *GetDDKeyColumnList() = 0;
virtual CUOFsFileList *GetPartitionFileList() = 0;
//-------------------------------------------//
// PRIVATE AREA
//-------------------------------------------//
private:
//-- Connectivity into DDOL and inside the cache
// Common part for regular table and MV that is used by MVs.
CDDTblUsedByMV *pddTblUsedByMV_;
// Pointer to the IUD log for this table
CDDTable *pddIUDLogTbl_;
// Pointer to the MV object, if the table is also an involved MV.
CRUMV *pMVInterface_;
// The list of pointers to objects (MVs) using this object.
// NOTE: THE LIST DOES NOT OWN THE REFERENCED OBJECTS
// (and therefore, does not deallocate them).
CRUMVList *pMVsUsingMe_;
// Auxiliary pointer lists
CRUMVList *pOnRequestMVsUsingMe_;
CRUMVList *pInvolvedMVsUsingMe_;
CRUMVList *pOnRequestInvolvedMVsUsingMe_;
CRUMVList *pIncInvolvedMVsUsingMe_;
private:
//-- Data structures used by various tasks
CRUKeyColumnList *pKeyColumnList_;
CDSStringList *pPartitionFileNamesList_;
// The emptiness check result vector
CRUEmpCheckVector *pEmpCheckVector_;
// The Duplicate Elimination level
CRUDeltaDef::DELevel deLevel_;
// A hash table with statistical data about the log.
// A distinct record in it corresponds to each non-
// empty epoch in the log.
CRUDeltaStatisticsMap *pStatMap_;
TInt64 timestamp_;
private:
//-- Status flags
// Is the table/log open in read-protected mode?
BOOL isRPOpenPending_;
BOOL isLogRPOpenPending_;
BOOL isUsedByIncrementalMJV_;
//-- Requirements flags
BOOL isDENeeded_;
BOOL isLongLockNeeded_;
BOOL isEmptyDeltaNeeded_;
private:
// Return the fully-qualified log name,
// with/without the namespace
CDSString GetLogFullName(const CDSString &nmsp, BOOL useNmsp);
};
// Declare the class CRUTblList through this macro
DECLARE_PTRLIST(REFRESH_LIB_CLASS, CRUTbl)
#endif