blob: 14443c3c0209c5c9e0cb376487c7b40d06cf3fe0 [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: MdamIntervalList.C
* Description: Implimentation for MDAM Interval List
*
*
* Created: 9/12/96
* Language: C++
*
*
*
*
********************************************************************************
*/
// -----------------------------------------------------------------------------
#include "ex_stdh.h"
#if defined ( NA_MDAM_EXECUTOR_DEBUG )
#include <iostream>
#endif /* NA_MDAM_EXECUTOR_DEBUG */
#include "MdamEndPoint.h"
#include "MdamIntervalList.h"
#include "MdamIntervalListIterator.h"
#include "MdamIntervalListMerger.h"
#if defined ( NA_MDAM_EXECUTOR_DEBUG_ILTF )
#include <stdio.h>
#endif /* NA_MDAM_EXECUTOR_DEBUG_ILTF */
// *****************************************************************************
// Member functions for class MdamIntervalList
// *****************************************************************************
// Constructor.
#if defined ( NA_MDAM_EXECUTOR_DEBUG_ILTF )
MdamIntervalList::MdamIntervalList(const Lng32 callerTag)
: firstIntervalPtr_(0), lastIntervalPtr_(0),
intervalListId_(NA_JulianTimestamp())
{
logEvent(5,0,-1,callerTag);
}
#else
MdamIntervalList::MdamIntervalList()
: firstIntervalPtr_(0), lastIntervalPtr_(0)
{}
#endif /* NA_MDAM_EXECUTOR_DEBUG_ILTF */
// Destructor.
MdamIntervalList::~MdamIntervalList()
{
#if defined ( NA_MDAM_EXECUTOR_DEBUG_ILTF )
logEvent(6);
#endif /* NA_MDAM_EXECUTOR_DEBUG_ILTF */
// This destructor should only be called after deleteAllIntervals() has been
// called to delete all the intervals. This destructor can't do this
// because access to the heap manager is needed.
#ifdef NA_MDAM_EXECUTOR_DEBUG
ex_assert(isEmpty(),
"MdamIntervalList::~MdamIntervalList() called for a non-empty interval list.");
#endif /* NA_MDAM_EXECUTOR_DEBUG */
}
// Appends an MdamInterval onto an MdamIntervalList. Warning: caller
// must ensure that the new interval is disjoint and in order. No
// integrity checks are performed.
MdamIntervalList & MdamIntervalList::append(MdamInterval * newIntervalPtr)
{
#if defined ( NA_MDAM_EXECUTOR_DEBUG_ILTF )
// logEvent(4,1);
#endif /* NA_MDAM_EXECUTOR_DEBUG_ILTF */
if (firstIntervalPtr_ == 0) // Empty list?
{
firstIntervalPtr_ = newIntervalPtr;
}
else
{
lastIntervalPtr_->setNextMdamIntervalPtr(newIntervalPtr);
};
lastIntervalPtr_ = newIntervalPtr;
newIntervalPtr->setNextMdamIntervalPtr(0);
return *this;
}
#if defined ( NA_MDAM_EXECUTOR_DEBUG_ILTF )
Lng32 MdamIntervalList::countIntervals() const
{
Lng32 intervalCount = 0;
MdamIntervalListIterator iterator(*this);
while(iterator() != 0)
{
intervalCount++;
};
return intervalCount;
}
#endif /* NA_MDAM_EXECUTOR_DEBUG_ILTF */
// Delete all the intervals in the list.
void MdamIntervalList::deleteAllIntervals
(FixedSizeHeapManager & mdamIntervalHeap,
FixedSizeHeapManager & mdamRefListEntryHeap)
{
#if defined ( NA_MDAM_EXECUTOR_DEBUG_ILTF )
logEvent(1,-countIntervals());
#endif /* NA_MDAM_EXECUTOR_DEBUG_ILTF */
MdamIntervalListIterator iterator(*this);
MdamInterval * intervalPtr = 0;
while((intervalPtr = iterator()) != 0)
{
intervalPtr->release(mdamRefListEntryHeap); // release the interval's resources
mdamIntervalHeap.releaseElement(intervalPtr); // return interval to free list
};
firstIntervalPtr_ = 0;
lastIntervalPtr_ = 0;
}
// Give all intervals from this list and put them in otherList.
// this list becomes empty.
void MdamIntervalList::giveAllIntervals(MdamIntervalList & otherList)
{
#if defined ( NA_MDAM_EXECUTOR_DEBUG_ILTF )
// Log for this list giving intervals.
logEvent(2,-countIntervals(),otherList.intervalListId_);
// Log for otherList receiving intervals.
otherList.logEvent(3,countIntervals(),intervalListId_);
#endif /* NA_MDAM_EXECUTOR_DEBUG_ILTF */
otherList.firstIntervalPtr_ = firstIntervalPtr_;
otherList.lastIntervalPtr_ = lastIntervalPtr_;
firstIntervalPtr_ = 0;
lastIntervalPtr_ = 0;
}
// This function inserts a single disjunct number into the reference list
// associated with each MdamInterval on the MdamIntervalList.
void MdamIntervalList::insertDisjunctNum(const Int32 disjunctNum,
FixedSizeHeapManager & mdamRefListEntryHeap)
{
MdamIntervalListIterator iterator(*this);
MdamInterval * intervalPtr = 0;
while((intervalPtr = iterator()) != 0)
{
intervalPtr->insertDisjunctNum(disjunctNum, mdamRefListEntryHeap);
};
}
// Performs an intersect operation on two interval lists to produce a
// result list. The this list and the otherList are inputs to the
// intersect operation. The result replaces the this list. The
// original interval list entries for the this list are deleted.
MdamIntervalList & MdamIntervalList::intersect
(const MdamIntervalList & otherList,
const ULng32 keyLen,
FixedSizeHeapManager & mdamIntervalHeap,
FixedSizeHeapManager & mdamRefListEntryHeap)
{
// Move entries from this into tempIntervalList.
#if defined ( NA_MDAM_EXECUTOR_DEBUG_ILTF )
MdamIntervalList tempIntervalList(1);
#else
MdamIntervalList tempIntervalList;
#endif /* NA_MDAM_EXECUTOR_DEBUG_ILTF */
giveAllIntervals(tempIntervalList);
MdamIntervalListMerger getNextPoint(&tempIntervalList,
&otherList,
keyLen);
MdamEndPoint endPoint1;
MdamEndPoint endPoint2;
getNextPoint(endPoint1);
while(endPoint1.exists())
{
if (getNextPoint.getActiveIntervals() == 2)
{
getNextPoint(endPoint2);
MdamInterval * tempIntervalPtr = new(mdamIntervalHeap)
MdamInterval(endPoint1, endPoint2);
append(tempIntervalPtr);
endPoint1 = endPoint2;
}
else
{
getNextPoint(endPoint1);
}; // end if
}; // end while
#if defined ( NA_MDAM_EXECUTOR_DEBUG_ILTF )
// Log entry for intervals resulting from the intersect operation.
logEvent(7,countIntervals(),otherList.intervalListId_);
#endif /* NA_MDAM_EXECUTOR_DEBUG_ILTF */
// Delete the original this list entries because the destructor
// can't.
tempIntervalList.deleteAllIntervals(mdamIntervalHeap,
mdamRefListEntryHeap);
return *this;
}
#if defined ( NA_MDAM_EXECUTOR_DEBUG_ILTF )
void MdamIntervalList::logEvent(const Lng32 functionId,
const Lng32 intervalCount,
const Int64 otherListId,
const Lng32 callerTag) const
{
Int64 eventTimestamp = NA_JulianTimestamp();
printf(" %I64i %I64i %li %li %I64i %li\n",
eventTimestamp,
intervalListId_,
functionId,
intervalCount,
otherListId,
callerTag);
}
#endif /* NA_MDAM_EXECUTOR_DEBUG_ILTF */
// Print functions.
#if defined ( NA_MDAM_EXECUTOR_DEBUG )
void MdamIntervalList::print(const char * header) const
{
cout << header << endl;
MdamIntervalListIterator iterator(*this);
MdamInterval * intervalPtr = 0;
while((intervalPtr = iterator()) != 0)
{
intervalPtr->print("Interval...");
};
}
void MdamIntervalList::printBrief() const
{
MdamIntervalListIterator iterator(*this);
MdamInterval * intervalPtr = 0;
while((intervalPtr = iterator()) != 0)
{
intervalPtr->printBrief();
};
}
#endif /* NA_MDAM_EXECUTOR_DEBUG */
// Performs a union operation on two interval lists to produce a
// result list. The list's intervals may have different
// MdamRefList*s associated with them. Any reference lists
// associated with otherList are ignored and disjunctNum is used
// instead. The this list and the otherList are inputs to the
// intersect operation. The result replaces the this list. The
// original interval list entries for the this list are deleted.
MdamIntervalList & MdamIntervalList::unionSeparateDisjuncts
(const MdamIntervalList & otherList,
const Int32 disjunctNum,
const ULng32 keyLen,
FixedSizeHeapManager & mdamIntervalHeap,
FixedSizeHeapManager & mdamRefListEntryHeap)
{
// Move entries from this into tempIntervalList.
#if defined ( NA_MDAM_EXECUTOR_DEBUG_ILTF )
MdamIntervalList tempIntervalList(2);
#else
MdamIntervalList tempIntervalList;
#endif /* NA_MDAM_EXECUTOR_DEBUG_ILTF */
giveAllIntervals(tempIntervalList);
MdamIntervalListMerger getNextPoint(&tempIntervalList,
&otherList,
keyLen);
MdamEndPoint currentEndPoint;
MdamEndPoint previousEndPoint;
// Track the active interval for each interval list. Zero means
// there is no active interval. This mechanism permits access
// to the corresponding reference list.
MdamInterval * intervalPtr0 = 0;
MdamInterval * intervalPtr1 = 0;
while(getNextPoint(currentEndPoint))
{
if (getNextPoint.getPreviousActiveIntervals() != 0
&& currentEndPoint.givesNonEmptyInterval(&previousEndPoint,keyLen))
{
// Create a new interval. The constructor will reverse the
// inclusion of end endpoint, if appropriate, and build
// the reference list.
MdamInterval * tempIntervalPtr = new(mdamIntervalHeap)
MdamInterval(previousEndPoint,
currentEndPoint,
intervalPtr0,
intervalPtr1,
disjunctNum,
mdamRefListEntryHeap);
// Append the new interval onto this list.
append(tempIntervalPtr);
}; // end if
// Adjust active reference lists.
currentEndPoint.adjustIntervalPtr(intervalPtr0, 0);
currentEndPoint.adjustIntervalPtr(intervalPtr1, 1);
// Save the current endpoint.
previousEndPoint = currentEndPoint;
if (currentEndPoint.end()){previousEndPoint.reverseInclusion();};
}; // end while
#if defined ( NA_MDAM_EXECUTOR_DEBUG_ILTF )
// Log entry for intervals resulting from the union operation.
logEvent(8,countIntervals(),otherList.intervalListId_);
#endif /* NA_MDAM_EXECUTOR_DEBUG_ILTF */
// Delete the original this list entries because the destructor
// can't.
tempIntervalList.deleteAllIntervals(mdamIntervalHeap,
mdamRefListEntryHeap);
return *this;
}
// Performs an union operation on two interval lists to produce a
// result list. The source lists have no MdamRefLists associated
// with them. The this list and the otherList are inputs to the
// union operation. The result replaces the this list. The
// original interval list entries for this list are deleted.
MdamIntervalList & MdamIntervalList::unionSameDisjunct
(const MdamIntervalList & otherList,
const ULng32 keyLen,
FixedSizeHeapManager & mdamIntervalHeap,
FixedSizeHeapManager & mdamRefListEntryHeap)
{
// Move entries from this into tempIntervalList.
MdamIntervalList tempIntervalList;
giveAllIntervals(tempIntervalList);
MdamIntervalListMerger getNextPoint(&tempIntervalList,
&otherList,
keyLen);
MdamEndPoint endPoint1;
MdamEndPoint endPoint2;
getNextPoint(endPoint1);
// If endPoint1 exists, it is a BEGIN endpoint.
while(endPoint1.exists())
{
while(getNextPoint.getActiveIntervals() >= 1)
{
getNextPoint(endPoint2);
}; // end while
// endPoint2 is an END endpoint.
MdamInterval * tempIntervalPtr = new(mdamIntervalHeap)
MdamInterval(endPoint1, endPoint2);
append(tempIntervalPtr);
getNextPoint(endPoint1);
}; // end while
// Delete the original this list entries because the destructor
// can't.
tempIntervalList.deleteAllIntervals(mdamIntervalHeap,
mdamRefListEntryHeap);
return *this;
}