blob: bcca8fc1c99a9dcdcab55b126e26fb564546fdb9 [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 EX_ESP_FRAG_DIR_H
#define EX_ESP_FRAG_DIR_H
/* -*-C++-*-
*****************************************************************************
*
* File: ex_esp_frag_dir.h
* Description: Fragment instance directory in the ESP
*
*
* Created: 1/22/96
* Language: C++
*
*
*
*
*****************************************************************************
*/
// -----------------------------------------------------------------------
#include "Ex_esp_msg.h"
#include "ComSqlexedbg.h"
#include "Globals.h"
// -----------------------------------------------------------------------
// Contents of this file
// -----------------------------------------------------------------------
class ExEspFragInstanceDir;
// -----------------------------------------------------------------------
// Forward references
// -----------------------------------------------------------------------
class ex_split_bottom_tdb;
class ex_split_bottom_tcb;
class ExEspStmtGlobals;
class MemoryMonitor;
class StatsGlobals;
// -----------------------------------------------------------------------
// Fragment instance directory in the ESP (multiple instances of multiple
// fragments from multiple owners)
// -----------------------------------------------------------------------
const Int32 NumFiTraceElements = 32;
// state name strings, must match with the enums below
static const char * FragmentInstanceStateName[] =
{
"UNUSED ",
"DOWNLOADED ",
"UNPACKED ",
"BUILT ",
"FIXED_UP ",
"READY_INACTIVE ",
"ACTIVE ",
"WAIT_TO_RELEASE",
"RELEASING_WORK ",
"RELEASING ",
"GOING_FATAL ",
"BROKEN "
};
class ExEspFragInstanceDir
{
friend class ExEspControlMessage;
public:
enum FragmentInstanceState
{
UNUSED, // unused entry, no ExEspFragInstance is allocated
DOWNLOADED, // fragment downloaded, globals but no tcb allocated
UNPACKED, // pointers relocated
BUILT, // tcb is now allocated (built)
FIXED_UP, // fixup method is now called, files are open
READY_INACTIVE, // ready to work but there is currently no work
ACTIVE, // tcb has current requests and its transid is active
WAIT_TO_RELEASE, // waiting to get replies from msgs to producer ESPs
RELEASING_WORK, // need to release work requests, tcb may be active
RELEASING, // release request for this instance has been received
GOING_FATAL, // frag's scheduler has received WORK_BAD_ERROR
BROKEN // error state, don't use statement
// Possible state transitions (all others should be considered illegal):
//
// UNUSED -> DOWNLOADED load message received, instance is
// initialized
// DOWNLOADED -> UNPACKED TDB tree got unpacked from load message
// UNPACKED -> BUILT TCB tree got built after unpack
// BUILT -> FIXED_UP first fixup message received
// READY_INACTIVE -> FIXED_UP second or later fixup message received
//
// FIXED_UP -> READY_INACTIVE first send top has opened send bottom
//
// READY_INACTIVE -> ACTIVE send bottom receives first request
//
// ACTIVE ->WAIT_TO_RELEASE Master sends release message. Frag
// dir now switches among frag instances
// while waiting for replies to msgs
// to producer ESPs.
// ACTIVE -> RELEASING_WORK last send bottom replies to last
// request
// WAIT_TO_RELEASE -> RELEASING_WORK all messages from producer ESPs
// replied
// RELEASING_WORK -> ACTIVE work message is released and
// there are still active requests
// RELEASING_WORK -> READY_INACTIVE work message is released and
// there are no more requests
//
// any state -> GOING_FATAL bad things happen
//
// (DOWNLOADED, UNPACKED, BUILT,
// FIXED_UP, READY_INACTIVE,
// RELEASING, GOING_FATAL,
// BROKEN) -> RELEASING release message received
//
// RELEASING -> UNUSED release message processed
//
};
ExEspFragInstanceDir(CliGlobals *cliGlobals,
CollHeap *heap,
CollHeap *exHeap,
StatsGlobals *statsGlobals);
~ExEspFragInstanceDir();
inline CollIndex getNumEntries() const { return instances_.entries(); }
inline Lng32 getNumMasters() const { return numMasters_; }
inline IpcEnvironment * getEnvironment() const
{ return cliGlobals_->getEnvironment(); }
inline CliGlobals *getCliGlobals() const
{return cliGlobals_; }
// convert key into handle and vice versa
ExFragInstanceHandle findHandle(const ExFragKey &key) const;
inline const ExFragKey & findKey(ExFragInstanceHandle handle) const
{ return instances_[handle]->key_; }
// get the top level tcb for an entry
inline ex_split_bottom_tcb * getTcb(ExFragInstanceHandle h) const
{ return instances_[h]->localRootTcb_; }
inline ExEspStmtGlobals *getGlobals(ExFragInstanceHandle h) const
{ return instances_[h]->globals_; }
ex_split_bottom_tcb *getExtractTop(const char *securityKey);
ExFragInstanceHandle addEntry(ExMsgFragment *msgFragment,
IpcConnection *connection);
void fixupEntry(ExFragInstanceHandle handle,
Lng32 numOfParentInstances,
ComDiagsArea &da);
// keep track of the activities that go on in the send bottom nodes,
// record open operation and arrival and finishing of requests
void openedSendBottom(ExFragInstanceHandle handle);
void startedSendBottomRequest(ExFragInstanceHandle handle);
void finishedSendBottomRequest(ExFragInstanceHandle handle);
void startedSendBottomCancel(ExFragInstanceHandle handle);
void finishedSendBottomCancel(ExFragInstanceHandle handle);
void startedLateCancelRequest(ExFragInstanceHandle handle);
void finishedLateCancelRequest(ExFragInstanceHandle handle);
Lng32 numLateCancelRequests(ExFragInstanceHandle handle);
// Do the ACTIVE->RELEASING_WORK transition
void finishedRequest(ExFragInstanceHandle handle,
NABoolean testAllQueues = FALSE);
// Do the ACTIVE->WAIT_TO_RELEASE transition
void hasReleaseRequest(ExFragInstanceHandle handle);
// release the entry and all its dependent entries
void releaseEntry(ExFragInstanceHandle handle);
// release the entries that lost their parent
void releaseOrphanEntries();
// mark in the entry that it no longer has a transid
void hasTransidReleaseRequest(ExFragInstanceHandle handle);
inline Lng32 getNumActiveInstances() { return numActiveInstances_; }
enum FragmentInstanceState getEntryState(ExFragInstanceHandle handle) const
{ return instances_[handle]->fiState_; }
ExMsgFragment * getFragment(ExFragInstanceHandle handle) const
{ return instances_[handle]->msgFragment_; }
ex_split_bottom_tcb *getTopTcb(ExFragInstanceHandle handle) const
{ return instances_[handle]->localRootTcb_; }
Lng32 getNumSendBottomRequests(ExFragInstanceHandle handle)
{ return instances_[handle]->numSendBottomRequests_; }
Lng32 getNumSendBottomCancels(ExFragInstanceHandle handle)
{ return instances_[handle]->numSendBottomCancels_; }
// work on all active fragment instances
void work(Int64 prevWaitTime);
class ExEspFragInstance
{
public:
ExFragKey key_; // pid,stmthandle,fragid triplet
ExFragInstanceHandle handle_; // index of the owning array
FragmentInstanceState fiState_; // state of this entry
ExFragDir::ExFragEntryType fragType_; // ESP or DP2 fragment
ExFragKey parentKey_; // parent fragment id
IpcConnection *controlConn_; // control connection used
Lng32 topNodeOffset_; // offset of top tcb in frag
ExMsgFragment *msgFragment_; // downloaded fragment buffer
ex_split_bottom_tdb *localRootTdb_; // root of this fragment
ex_split_bottom_tcb *localRootTcb_; // root of this fragment
ExEspStmtGlobals *globals_; // global statement vars
Lng32 numSendBottomRequests_; // # client work requests
Lng32 numSendBottomCancels_; // # client cancel requests
Lng32 numLateCancelRequests_; // # late cancels below
NABoolean displayInGui_; // enable executor GUI
unsigned short mxvOfOriginator_;// plan version of the plan fragment
unsigned short planVersion_; // plan version of the plan fragment
char *queryId_;
Lng32 queryIdLen_;
};
// Check the plan version of the sent fragment
Lng32 checkPlanVersion(const ExEspFragInstance * entry,
ComDiagsArea& da);
StatsGlobals *getStatsGlobals() { return statsGlobals_; }
NAHeap *getStatsHeap() { return statsHeap_; }
pid_t getPid() { return pid_;};
pid_t getTid() { return tid_;};
Int32 getCpu() { return cpu_; }
Long &getSemId() { return semId_; };
NAHeap *getLocalStatsHeap();
// A function to establish database user identity for this
// process. On Linux, ContextCli data members will be updated. On
// other platforms this call is a no-op.
void setDatabaseUserID(Int32 userID, const char *userName);
NABoolean getUserIDEstablished() const { return userIDEstablished_; }
// For fragment instance trace
struct FiStateTrace
{
ExFragInstanceHandle fragId_;
FragmentInstanceState fiState_;
Int32 lineNum_;
};
Int32 printALiner(Int32 lineno, char *buf);
static Int32 getALine(void * mine, Int32 lineno, char * buf)
{ return ((ExEspFragInstanceDir *) mine)->printALiner(lineno, buf); }
void initFiStateTrace();
FragmentInstanceState setFiState(ExFragInstanceHandle fragId,
FragmentInstanceState newState,
Int32 linenum);
private:
// how many instances need to have their scheduler called?
Lng32 numActiveInstances_;
// no instance has a number >= to this
CollIndex highWaterMark_;
// an array with pointers to all downloaded fragment instances
ARRAY(ExEspFragInstance *) instances_;
// how many master ESPs are we talking to?
Lng32 numMasters_;
CliGlobals *cliGlobals_;
CollHeap *heap_;
CollHeap *exHeap_;
StatsGlobals *statsGlobals_;
NAHeap *statsHeap_;
pid_t pid_;
pid_t tid_;
Int32 cpu_;
Long semId_;
NAHeap *localStatsHeap_;
// A boolean to indicate whether this process has already updated
// the ContextCli user identity. Only meaningful on Linux.
NABoolean userIDEstablished_;
// Fragment instance trace
FiStateTrace fiStateTrace_[NumFiTraceElements];
Int32 fiTidx_;
void *traceRef_;
// private methods
ExEspFragInstance * findEntry(const ExFragKey &key);
void destroyEntry(ExFragInstanceHandle handle);
void traceIdleMemoryUsage();
};
// -----------------------------------------------------------------------
// Message stream to receive requests through the control connection
// (such as load, fixup, ...)
// -----------------------------------------------------------------------
class ExEspControlMessage : public IpcMessageStream
{
public:
ExEspControlMessage(ExEspFragInstanceDir *fragInstanceDir,
IpcEnvironment *ipcEnvironment,
CollHeap *heap);
virtual ~ExEspControlMessage();
private:
// private data members
// fragment instance directory, to find instances referred to in requests
ExEspFragInstanceDir *fragInstanceDir_;
CollHeap *heap_;
// store info about the received request (key, handle)
ExFragKey currKey_;
ExFragInstanceHandle currHandle_;
// private methods
// callback functions
virtual void actOnSend(IpcConnection *connection);
virtual void actOnSendAllComplete();
virtual void actOnReceive(IpcConnection *connection);
// act on individual requests
void actOnLoadFragmentReq(IpcConnection *connection,
ComDiagsArea & da);
void actOnFixupFragmentReq(ComDiagsArea & da);
void actOnReleaseFragmentReq(ComDiagsArea & da);
void actOnReqForSplitBottom(IpcConnection *connection);
void incReplyMsg(Int64 msgBytes);
};
#endif /* EX_ESP_FRAG_DIR_H */