blob: 535546c77304b59adc35851caee1808c342a9cf9 [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 @@@
**********************************************************************/
/* -*-C++-*-
*****************************************************************************
*
* File: GenFragmentDir.C
* Description: Methods for fragment directory
*
*
* Created: 12/6/95
* Language: C++
*
*
*
*
*****************************************************************************
*/
#include "FragmentDir.h"
//#include "Generator.h"
#include "ComSpace.h"
// -----------------------------------------------------------------------
// forward declarations
// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
// Methods for class FragmentDir
// -----------------------------------------------------------------------
FragmentDir::FragmentDir(CollHeap * heap)
: heap_(heap)
{
currentFragmentId_ = NULL_COLL_INDEX;
allEspFragmentsNeedTransaction_ = FALSE;
entries_ = new(heap_) NAArray<FragmentDirEntry*>(heap_);
}
FragmentDir::~FragmentDir()
{
// before getting rid of the array, delete all the Space objects
// that are owned by the directory entries. NOTE: don't delete the
// space objects in FragmentDirEntry::~FragmentDirEntry, since the
// ARRAY collection copies and moves entries around which causes the
// destructor to be called when such a deletion would be wrong.
for (CollIndex i = 0; i < entries(); i++)
if (heap_
) {
// first free blocks allocated by this space
(*entries_)[i]->space_->freeBlocks();
// now deallocate the Space object itself. We need this two step
// approach, because Space is not derived from NABasicObject
heap_->deallocateMemory((*entries_)[i]->space_);
}
else
delete (*entries_)[i]->space_;
}
CollIndex FragmentDir::pushFragment(FragmentTypeEnum type,
Lng32 numESPs,
const PartitioningFunction *partFunc,
Lng32 partInputDataLength)
{
CollIndex newIndex = entries(); // assume a dense array
FragmentDirEntry * fde = new(heap_) FragmentDirEntry();
// (*entries_).insertAt(newIndex,FragmentDirEntry());
entries_->insertAt(newIndex, fde);
FragmentDirEntry *newEntry = (*entries_)[newIndex];
// now fill the new entry with stuff
newEntry->type_ = type;
// create new space manager for fragment
newEntry->space_ = new(heap_) Space(Space::GENERATOR_SPACE);
newEntry->space_->setParent(heap_); // was NAHeap*-casted, but this has MI-problems
newEntry->parentIndex_ = currentFragmentId_;
newEntry->topNode_ = NULL; // will be set later
newEntry->numESPs_ = numESPs;
newEntry->partFunc_ = partFunc;
newEntry->partInputDataLength_ = partInputDataLength;
newEntry->needsTransaction_ = FALSE;
newEntry->containsPushedDownOperators_ = FALSE;
newEntry->soloFragment_ = FALSE;
// check whether we already know that we need a transaction
if (type == ESP && allEspFragmentsNeedTransaction_)
setNeedsTransaction(newIndex);
// the newly created fragment becomes the current one
currentFragmentId_ = newIndex;
return currentFragmentId_;
}
CollIndex FragmentDir::popFragment()
{
// although the method is called "pop", don't destroy the entry
// in the fragment directory, just return the index of its parent fragment
currentFragmentId_ = (*entries_)[currentFragmentId_]->parentIndex_;
// NAAssert(currentFragmentId_ < entries(),"NOT currentFragmentId_ < entries()");
assert(currentFragmentId_ < entries());
return currentFragmentId_;
}
void FragmentDir::removeFragment()
{
CollIndex lastEntry = entries_->entries() - 1;
if (heap_
) {
// first call destructor to free blocks allocated by this space
(*entries_)[lastEntry]->space_->~Space();
// now deallocate the Space object itself. We need this two step
// approach, because Space is not derived from NABasicObject
heap_->deallocateMemory((*entries_)[lastEntry]->space_);
}
else
delete (*entries_)[lastEntry]->space_;
currentFragmentId_ = (*entries_)[lastEntry]->parentIndex_;
entries_->remove(lastEntry);
}
Lng32 FragmentDir::getFragmentLength(CollIndex ix) const
{
Lng32 result = (*entries_)[ix]->space_->getAllocatedSpaceSize();
// We want to align each fragment on an 8 byte boundary, so round
// up the length to the next multiple of 8
result = ((result-1)/8 + 1) * 8;
return result;
}
void FragmentDir::setAllEspFragmentsNeedTransaction()
{
// remember this for future fragments...
allEspFragmentsNeedTransaction_ = TRUE;
// ...and update all existing fragments
for (CollIndex i = 0; i < entries(); i++)
if (getType(i) == ESP)
setNeedsTransaction(i);
}
Lng32 FragmentDir::getTotalLength() const
{
Lng32 result = 0;
for (CollIndex i = 0; i < entries(); i++)
result += getFragmentLength(i);
return result;
}
NABoolean FragmentDir::containsESPLayer()
{
for (CollIndex i = 0; i < entries(); i++)
if (getPartitioningFunction(i) != NULL && getType(i) == FragmentDir::ESP)
{
return TRUE;
}
return FALSE;
}
FragmentDirEntry::FragmentDirEntry()
{ type_ = 99;
space_ = NULL;
parentIndex_ = 0;
topNode_ = NULL;
numESPs_ = 0;
espLevel_ = 0;
partFunc_ = NULL;
partInputDataLength_ = 0;
numBMOs_ = 0;
BMOsMemoryUsage_ = 0;
needsTransaction_ = FALSE;
soloFragment_ = FALSE;
}