blob: 78c91bebf5d0f8a257820b6d97eaaa6c5fa41845 [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 COSTVECTOR_HDR
#define COSTVECTOR_HDR
/* -*-C++-*-
**************************************************************************
*
* File: CostVector.h
* Description: Cost
* Created: 11/12/96
* Language: C++
*
* Purpose: Split from Cost.h to remove header file dependency loop
*
*
*
**************************************************************************
*/
// -----------------------------------------------------------------------
#include "NADefaults.h"
#include "BaseTypes.h"
#include "NAType.h"
#include "ValueDesc.h"
#include "CostScalar.h"
#include "opt.h"
#include "CmpStatement.h"
// -----------------------------------------------------------------------
// Forward references.
// -----------------------------------------------------------------------
class NAType;
class ValueId;
class ValueIdSet;
class ValueIdList;
class ItemExpr;
class PerformanceGoal;
class CostWeight;
// -----------------------------------------------------------------------
// The following classes are defined in this file.
// -----------------------------------------------------------------------
class CostVector;
class SimpleCostVector;
// -----------------------------------------------------------------------
// A vector that contains various resource consumption and elapsed
// time metrics (base class).
// -----------------------------------------------------------------------
class CostVector : public NABasicObject
{
public:
virtual ~CostVector() {}
// A virtual method that returns the number of entries.
virtual Lng32 entries() const = 0;
// A virtual method that provides access to a specific entry.
virtual CostScalar operator[] (Lng32 ix) const = 0;
// A virtual method that provides a string describing individual components
virtual const NAString getDetailDesc(const DefaultToken ownline, const char *prefix = "") const = 0;
// A virtual copy constructor.
virtual CostVector * copy() const = 0;
}; // class CostVector
//<pb>
// -----------------------------------------------------------------------
// The following enum gives a name and a number to each of the
// entities that are measured for computing the cost of a plan.
//
/*j Before 04/12/2001 SimpleCostVector had 12 components as of now it
has been reduced to FIVE components for better performance. And the
enum has been changed as following.
On 10-16-2006: In order to implement SCM, this enum has been extended
to have FIVE new components.
CPU_TIME: Total time of CPU = CPU_COST * FudgeFactor(CPU)
IO_TIME: Total time of IO =
NUM_SEEKS * FF(NUM_SEEKS) + NUM_BYTES * FF(NUM_BYTES);
MSG_TIME: Total time for messages =
NUM_LOCAL_MESSAGES * FF(NUM_LOCAL_MESSAGES) +
KB_LOCAL_MESAGES * FF(KB_LOCAL_MESAGES) +
NUM_REMOTE_MESSAGES * FF(NUM_REMOTE_MESSAGES) +
KB_REMOTE_MESSAGES * FF(KB_REMOTE_MESSAGES);
IDLE_TIME : The time for which an operator is expected to not
perform any useful work. Refered to as blk_idlt in the Cost Estimation
document.
// Begin SCM
TC_PROC : Represents total number of tuples processed.
TC_PROD : Represents total number of tuples produced.
TC_SENT : Represents total number of tuples sent to parent.
IO_RAND : Total number of random IOs.
IO_SEQ : Total number of sequential IOs.
// End SCM
NUM_PROBES: Number of times that the operator is run, should be the last one.
As we are not using Normal, Persitent Memory and Disk Usage those
components have been eliminated from the vector for now.
The below are the 12 components which were used previously if a need
arises where we need to have more specific cost then we might change
back to using one of these components and that is the reason these line
have not been deleted. May be we will need it in future.
j*/
// CPU_COST:
// A count of CPU instructions that are expected to be executed.
// A value of 1 means 1000 machine instructions.
// NUM_SEEKS:
// Number of random I/Os and positionings for sequential reads
// NUM_KBYTES:
// Kilobytes of I/O transferred
// note: NUM_SEEKS and NUM_BYTES do not incorporate the effect of
// cache
// NORMAL_MEMORY:
// Amount of memory, in KB, used to hold working buffers and hash tables
// PERSISTENT_MEMORY
// Amount of memory, in KB, which persists after operation completion
// NUM_LOCAL_MESSAGES:
// Number of local messages
// KB_LOCAL_MESAGES:
// Kilobytes of local messages
// NUM_REMOTE_MESSAGES:
// Number of remote messages
// KB_REMOTE_MESSAGES:
// Kilobytes of remote messages
// IDLE_TIME:
// The time for which an operator is expected to not perform
// any useful work. Refered to as blk_idlt in the Cost Estimation document.
// DISK_USAGE:
// Disk space utilization, in 1KB units, for creating intermediate
// results of processing that are transient in nature.
// NUM_PROBES:
// Number of times that the operator is run
// -----------------------------------------------------------------------
enum SimpleCostCountersEnum
{
CPU_TIME = 0, // total time taken by cpu
IO_TIME = 1, // total time taken by IO
MSG_TIME = 2, // total time taken by messages
IDLE_TIME = 3, // waiting time
TC_PROC = 4, // total number of tuples processed
TC_PROD = 5, // total number of tuples produced
TC_SENT = 6, // total number of tuples exchanged
IO_RAND = 7, // total number of random IOs.
IO_SEQ = 8, // total number of sequential IOs.
NUM_PROBES = 9, // number of times the plan is run
COUNT_OF_SIMPLE_COST_COUNTERS = 10 // $$$$ KEEP AS THE FINAL MEMBER
/*j
CPU_COST = 0, // A count of CPU instructions that are expected to be
// executed. A value of 1 means 1000 machine
// instructions.
NUM_SEEKS = 1, // number of random io's and positioning for sequential
// reads.
NUM_KBYTES = 2, // kilobytes of I/O transfered
NORMAL_MEMORY = 3, // amount of memory, in KB, used for buffers and tables
PERSISTENT_MEMORY = 4, // amount of memory, in KB, persisting after
// operation
NUM_LOCAL_MESSAGES = 5, // number of local messages
KB_LOCAL_MESSAGES = 6, // Kilobytes of local messages
NUM_REMOTE_MESSAGES = 7, // Number of remote messages
KB_REMOTE_MESSAGES = 8, // Kilobytes of remote messages
IDLE_TIME = 9, // Time not doing useful work
DISK_USAGE = 10, // Temporary disk space in KB units
NUM_PROBES = 11, // number of times the plan is run
COUNT_OF_SIMPLE_COST_COUNTERS = 12
j*/ // $$$$ KEEP AS THE FINAL MEMBER
};
//<pb>
// -----------------------------------------------------------------------
// A cost vector, implemented with CostScalar objects
// -----------------------------------------------------------------------
class SimpleCostVector : public CostVector
{
//-------------------------------
// Friend operators and functions
//-------------------------------
friend SimpleCostVector operator+ (const SimpleCostVector &v1,
const SimpleCostVector &v2);
friend SimpleCostVector operator- (const SimpleCostVector &v1,
const SimpleCostVector &v2);
friend SimpleCostVector operator* (const SimpleCostVector &vector,
const CostScalar &scalar);
friend SimpleCostVector operator/ (const SimpleCostVector &vector,
const CostScalar &scalar);
friend SimpleCostVector blockingAdd(const SimpleCostVector &v1,
const SimpleCostVector &v2,
const ReqdPhysicalProperty* const rpp);
friend SimpleCostVector overlapAdd (const SimpleCostVector &v1,
const SimpleCostVector &v2);
friend SimpleCostVector overlapAddUnary (const SimpleCostVector &v1,
const SimpleCostVector &v2);
friend SimpleCostVector etMINOF (const SimpleCostVector &v1,
const SimpleCostVector &v2,
const ReqdPhysicalProperty* const rpp);
friend SimpleCostVector etMAXOF (const SimpleCostVector &v1,
const SimpleCostVector &v2,
const ReqdPhysicalProperty* const rpp);
friend SimpleCostVector vecMINOF (const SimpleCostVector &v1,
const SimpleCostVector &v2);
friend SimpleCostVector vecMAXOF (const SimpleCostVector &v1,
const SimpleCostVector &v2);
friend NABoolean isLowerBound (const SimpleCostVector &v1,
const SimpleCostVector &v2);
public:
// ---------------------------------------------------------------------
// Constructors (simple, specify costs, copy constructor)
// Used by OCM.
// ---------------------------------------------------------------------
SimpleCostVector(const CostScalar & CPUTime = csZero,
const CostScalar & IOTime = csZero,
const CostScalar & MSGTime = csZero,
const CostScalar & idleTime = csZero,
const CostScalar & numProbes = csOne
);
/*j
const CostScalar & cpuCost = csZero,
const CostScalar & numSeeks = csZero,
const CostScalar & numKBytes = csZero,
const CostScalar & normalMemory = csZero,
const CostScalar & persistentMemory = csZero,
const CostScalar & numLocalMessages = csZero,
const CostScalar & kbLocalMessages = csZero,
const CostScalar & numRemoteMessages = csZero,
const CostScalar & kbRemoteMessages = csZero,
const CostScalar & idleTime = csZero,
const CostScalar & diskUsage = csZero,
const CostScalar & numProbes = csOne
j*/
// Used by SCM
SimpleCostVector(const CostScalar & CPUTime,
const CostScalar & IOTime,
const CostScalar & MSGTime,
const CostScalar & idleTime,
const CostScalar & tcProc,
const CostScalar & tcProd,
const CostScalar & tcSent,
const CostScalar & ioRand,
const CostScalar & ioSeq,
const CostScalar & numProbes
);
SimpleCostVector(const SimpleCostVector &other);
virtual CostVector* copy() const
{ return new(CmpCommon::statementHeap()) SimpleCostVector(*this); }
// ---------------------------------------------------------------------
// Destructor
// ---------------------------------------------------------------------
~SimpleCostVector() {}
// ---------------------------------------------------------------------
// Arithmetic operators for a SimpleCostVector. They are vector-oriented,
// as opossed to blockingAdd, overlappedAdd and repeatedOverlappedAdd.
// Please see below.
// ---------------------------------------------------------------------
SimpleCostVector & operator = (const SimpleCostVector &other);
// Simple addition of vectors; does not affect the number of probes, and they
// must be the same in both vectors
SimpleCostVector & operator += (const SimpleCostVector &other);
// Simple substraction of vectors; does not affect the number of probes,
// and they must be the same in both vectors; all negatives in the result
// are set to zero
SimpleCostVector & operator -= (const SimpleCostVector &other);
// Simple multiplication of vector by an scalar; does not affect memory
// components or the number of probes
SimpleCostVector & operator *= (const CostScalar &other);
// Simple division of vector by an scalar; does not affect memory
// components or the number of probes
SimpleCostVector & operator /= (const CostScalar &other);
// ---------------------------------------------------------------------
// Operators to measure costs in execution tree.
// ---------------------------------------------------------------------
// -- Overlapped addition of two operators. They are assumed to be executing
// concurrently in the same process.
const SimpleCostVector& overlappedAdd(const SimpleCostVector & other);
// -- Repeated overlapped addition. It does not apply to memory, either
// normal or persistent.
const SimpleCostVector& repeatedOverlappedAdd(const Lng32 times);
// ---------------------------------------------------------------------
// scaleUpByNumProbes() scales up a simple cost vector by its number of
// probes. Memory and disk space are considered to be recyclable over
// probes, and hence not scaled up by this method.
// ---------------------------------------------------------------------
const SimpleCostVector& scaleUpByNumProbes();
// ---------------------------------------------------------------------
// scaleUpByCountOfCPUs() scales up a simple cost vector by the number
// of CPUs. This is typically used to convert a simple cost vector which
// tracks resource usage on a CPU to another simple cost vector which
// tracks total resource usage over all CPUs. All components except the
// no of probes are scaled up.
// ---------------------------------------------------------------------
const SimpleCostVector& scaleUpByCountOfCPUs(const Lng32 countOfCPUs);
// ---------------------------------------------------------------------
// scaleByValue() scales the vector by a specified scalar leaving only
// number of probes unaffected.
// ---------------------------------------------------------------------
SimpleCostVector& scaleByValue(const CostScalar &scalar);
//----------------------------------------------------------------------
// sets each element of vector to given value; number of probes is not
// changed
//----------------------------------------------------------------------
void setToValue(const CostScalar &);
// -- Sets to zero all components
const SimpleCostVector& reset();
const SimpleCostVector&
enforceUpperBound(const SimpleCostVector& upperBoundVector);
// ---------------------------------------------------------------------
// Miscellaneous functions.
// ---------------------------------------------------------------------
// This routine has the effect of setting the number of probes
// to the input factor and scaling all other members accordingly
// with the exception of the memory components. The intention
// is to be able to do operations between the resulting vector
// and another vector whose number of probes is factor.
const SimpleCostVector& normalize(const CostScalar & factor);
SimpleCostVector getNormalizedVersion(const CostScalar & factor) const;
// Indicate whether or not this vector is a zero vector.
NABoolean isZeroVector() const;
NABoolean isZeroVectorWithProbes() const;
// ---------------------------------------------------------------------
// Accessor functions for the elements of the SimpleCostVector
// ---------------------------------------------------------------------
CostScalar getCounter(Lng32 index) const
{
CMPASSERT((index >= 0) AND (index < COUNT_OF_SIMPLE_COST_COUNTERS));
return counter_[index];
}
// -- cpu time
inline const CostScalar& getCPUTime() const
{ return counter_[CPU_TIME]; }
// -- total time spent
CostScalar getElapsedTime(const ReqdPhysicalProperty* const rpp) const;
// -- total time spent
CostScalar getElapsedTime(const PerformanceGoal& goal,
const CostWeight* const vectorWeight = NULL) const;
// NCM specific method.
CostScalar getElapsedTime() const;
// -- time spent doing input/output operations
inline const CostScalar& getIOTime() const
{ return counter_[IO_TIME]; }
// -- time spent processing messages
inline const CostScalar& getMessageTime() const
{ return counter_[MSG_TIME]; }
// -- time spent without doing useful work
inline const CostScalar& getIdleTime() const
{ return counter_[IDLE_TIME]; }
// For SCM
// get tuples processed
inline const CostScalar& getTcProc() const
{ return counter_[TC_PROC]; }
// get tuples produced
inline const CostScalar& getTcProd() const
{ return counter_[TC_PROD]; }
// get tuples sent
inline const CostScalar& getTcSent() const
{ return counter_[TC_SENT]; }
// get Random Ios
inline const CostScalar& getIoRand() const
{ return counter_[IO_RAND]; }
// get sequential Ios
inline const CostScalar& getIoSeq() const
{ return counter_[IO_SEQ]; }
// -- number of times the plan is run
inline const CostScalar& getNumProbes() const
{ return counter_[NUM_PROBES]; }
virtual const NAString getDetailDesc(const DefaultToken ownline, const char *prefix = "") const;
/*
/*j // -- temporary disk space
inline const CostScalar& getDiskUsage() const
{ return counter_[DISK_USAGE]; }
// -- normal memory
inline const CostScalar& getNormalMemory() const
{ return counter_[NORMAL_MEMORY];}
// -- amount of memory persisting after operator has been used
inline const CostScalar& getPersistentMemory() const
{ return counter_[PERSISTENT_MEMORY]; }
j*/
// ---------------------------------------------------------------------
// Mutator functions for the elements of the SimpleCostVector
// ---------------------------------------------------------------------
//////////////////// SETTING CPU TIME ////////////////////////
// -- cpu cost
inline void setCPUTime(const CostScalar & value)
{
counter_[CPU_TIME] = value; }
// set the cpu time by converting the instructions passed into time
inline void setInstrToCPUTime(const CostScalar & value)
{
counter_[CPU_TIME] = value * CURRSTMT_OPTDEFAULTS->getTimePerCPUInstructions();
}
// add to cpu time by converting the instructions passed into time
inline void addInstrToCPUTime(const CostScalar & value)
{
counter_[CPU_TIME] += value * CURRSTMT_OPTDEFAULTS->getTimePerCPUInstructions();
}
/////////////////// SETTING IO TIME /////////////////////////
// -- Elapsed IO Calculated by adding cost of seeks & Kbytes transfer
inline void setIOTime(const CostScalar & value)
{ counter_[IO_TIME] = value; }
inline void addSeeksToIOTime(const CostScalar & value)
{
counter_[IO_TIME] += value * CURRSTMT_OPTDEFAULTS->getTimePerSeek();
}
inline void addKBytesToIOTime(const CostScalar & value)
{
counter_[IO_TIME] += value * CURRSTMT_OPTDEFAULTS->getTimePerSeqKb();
}
/////////////// SETTING MESSAGES TIME /////////////////
// Calcuating Elapsed MSG by adding the num of Local messages,
// kbytes of local messages, Remote messages & kbytes for remote msgs.
inline void setMSGTime(const CostScalar & value)
{
counter_[MSG_TIME] = value;
}
inline void addNumLocalToMSGTime(const CostScalar & value)
{
counter_[MSG_TIME] += value * CURRSTMT_OPTDEFAULTS->getTimePerLocalMsg();
}
inline void addKBLocalToMSGTime(const CostScalar & value)
{
counter_[MSG_TIME] += value * CURRSTMT_OPTDEFAULTS->getTimePerKbOfLocalMsg();
}
inline void addNumRemoteToMSGTime(const CostScalar & value)
{
counter_[MSG_TIME] += value * CURRSTMT_OPTDEFAULTS->getTimePerRemoteMsg();
}
inline void addKBRemoteToMSGTime(const CostScalar & value)
{ counter_[MSG_TIME] += value * CURRSTMT_OPTDEFAULTS->getTimePerKbOfRemoteMsg();
}
///////////// SETTING IDLE TIME /////////////////////////////////
// -- time spent without doing useful work
inline void setIdleTime(const CostScalar & value)
{ counter_[IDLE_TIME] = value; }
inline void addToIdleTime(const CostScalar & value)
{ counter_[IDLE_TIME] += value; }
inline void addToCpuTime(const CostScalar & value)
{ counter_[CPU_TIME] += value; }
////////////////// SET METHODS FOR SCM /////////////////////////////
inline void setTcProc(const CostScalar & value)
{
counter_[TC_PROC] = value;
}
inline void setTcProd(const CostScalar & value)
{
counter_[TC_PROD] = value;
}
inline void setTcSent(const CostScalar & value)
{
counter_[TC_SENT] = value;
}
inline void setIoRand(const CostScalar & value)
{
counter_[IO_RAND] = value;
}
inline void setIoSeq(const CostScalar & value)
{
counter_[IO_SEQ] = value;
}
//////////////////// SETTING NUMBER OF PROBES /////////////////////
// -- number of times the plan is run
inline void setNumProbes(const CostScalar & value)
{ counter_[NUM_PROBES] = value; }
inline void addToNumProbes(const CostScalar & value)
{ counter_[NUM_PROBES] += value; }
////////////////////////////// END //////////////////////////////////
/*j
inline void setDiskUsage(const CostScalar & value)
{ counter_[DISK_USAGE] = value; }
inline void addToDiskUsage(const CostScalar & value)
{ counter_[DISK_USAGE] += value; }
// -- amount of memory to hold buffers and tables
inline void setNormalMemory(const CostScalar & value)
{ counter_[NORMAL_MEMORY] = value; }
inline void addToNormalMemory(const CostScalar & value)
{ counter_[NORMAL_MEMORY] += value; }
// -- amount of memory persisting after operator has been used
inline void setPersistentMemory(const CostScalar & value)
{ counter_[PERSISTENT_MEMORY] = value; }
inline void addToPersistentMemory(const CostScalar & value)
{ counter_[PERSISTENT_MEMORY] += value; }
j*/
// -- prints all members of this class
void print(FILE* pfp = stdout) const;
// ---------------------------------------------------------------------
// Overloaded indexing operator for accessing individual elements.
// ---------------------------------------------------------------------
virtual Lng32 entries() const;
virtual CostScalar operator[] (Lng32 ix) const;
private:
CostScalar counter_[COUNT_OF_SIMPLE_COST_COUNTERS];
}; // class SimpleCostVector
//----------------------------------------------------------------------
// Needed for passing pointers to SimpleCostVector objects as reference
// parameters.
//----------------------------------------------------------------------
typedef SimpleCostVector* CostVecPtr;
#endif /* COSTVECTOR_HDR */