Cloned library of VTK-5.0.0 with extra build files for internal package management.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

233 lines
5.7 KiB

2 years ago
/*=========================================================================
Program: Visualization Toolkit
Module: $RCSfile: vtkPriorityQueue.cxx,v $
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
#include "vtkPriorityQueue.h"
#include "vtkObjectFactory.h"
vtkCxxRevisionMacro(vtkPriorityQueue, "$Revision: 1.32 $");
vtkStandardNewMacro(vtkPriorityQueue);
// Instantiate priority queue with default size and extension size of 1000.
vtkPriorityQueue::vtkPriorityQueue()
{
this->Size = 0;
this->Extend = 1000;
this->Array = NULL;
this->MaxId = -1;
this->ItemLocation = vtkIdTypeArray::New();
}
// Allocate priority queue with specified size and amount to extend
// queue (if reallocation required).
void vtkPriorityQueue::Allocate(const vtkIdType sz, const vtkIdType ext)
{
this->ItemLocation->Allocate(sz,ext);
for (vtkIdType i=0; i < sz; i++)
{
this->ItemLocation->SetValue(i,-1);
}
this->Size = ( sz > 0 ? sz : 1);
if ( this->Array != NULL )
{
delete [] this->Array;
}
this->Array = new vtkPriorityQueue::Item[sz];
this->Extend = ( ext > 0 ? ext : 1);
this->MaxId = -1;
}
// Destructor for the vtkPriorityQueue class
vtkPriorityQueue::~vtkPriorityQueue()
{
this->ItemLocation->Delete();
if ( this->Array )
{
delete [] this->Array;
}
}
// Insert id with priority specified.
void vtkPriorityQueue::Insert(double priority, vtkIdType id)
{
vtkIdType i, idx;
vtkPriorityQueue::Item temp;
// check and make sure item hasn't been inserted before
if ( id <= this->ItemLocation->GetMaxId() &&
this->ItemLocation->GetValue(id) != -1 )
{
return;
}
// start by placing new entry at bottom of tree
if ( ++this->MaxId >= this->Size )
{
this->Resize(this->MaxId + 1);
}
this->Array[this->MaxId].priority = priority;
this->Array[this->MaxId].id = id;
if ( id >= this->ItemLocation->GetSize() ) //might have to resize and initialize
{
vtkIdType oldSize = this->ItemLocation->GetSize();
this->ItemLocation->InsertValue(id,this->MaxId);
for (i=oldSize; i < this->ItemLocation->GetSize(); i++)
{
this->ItemLocation->SetValue(i, -1);
}
this->ItemLocation->SetValue(id,this->MaxId);
}
this->ItemLocation->InsertValue(id,this->MaxId);
// now begin percolating towards top of tree
for ( i=this->MaxId;
i > 0 && this->Array[i].priority < this->Array[(idx=(i-1)/2)].priority;
i=idx)
{
temp = this->Array[i];
this->ItemLocation->SetValue(temp.id,idx);
this->Array[i] = this->Array[idx];
this->ItemLocation->SetValue(this->Array[idx].id,i);
this->Array[idx] = temp;
}
}
// Simplified call for easier wrapping for Tcl.
vtkIdType vtkPriorityQueue::Pop(vtkIdType location)
{
double priority;
return this->Pop(location, priority);
}
// Removes item at specified location from tree; then reorders and
// balances tree. The location == 0 is the root of the tree.
vtkIdType vtkPriorityQueue::Pop(vtkIdType location, double &priority)
{
vtkIdType id, i, j, idx;
vtkPriorityQueue::Item temp;
if ( this->MaxId < 0 )
{
return -1;
}
id = this->Array[location].id;
priority = this->Array[location].priority;
// move the last item to the location specified and push into the tree
this->Array[location].id = this->Array[this->MaxId].id;
this->Array[location].priority = this->Array[this->MaxId].priority;
this->ItemLocation->SetValue(this->Array[location].id,location);
this->ItemLocation->SetValue(id,-1);
if ( --this->MaxId <= 0 )
{
return id;
}
// percolate into the tree
for ( j=0, i=location; i <= (this->MaxId-1)/2; i=j )
{
idx = 2*i + 1;
if ( this->Array[idx].priority < this->Array[idx+1].priority ||
idx == this->MaxId )
{
j = idx;
}
else
{
j = idx + 1;
}
if ( this->Array[i].priority > this->Array[j].priority )
{
temp = this->Array[i];
this->ItemLocation->SetValue(temp.id,j);
this->Array[i] = this->Array[j];
this->ItemLocation->SetValue(this->Array[j].id,i);
this->Array[j] = temp;
}
else
{
break;
}
}
return id;
}
// Protected method reallocates queue.
vtkPriorityQueue::Item *vtkPriorityQueue::Resize(const vtkIdType sz)
{
vtkPriorityQueue::Item *newArray;
vtkIdType newSize;
if (sz >= this->Size)
{
newSize = this->Size + sz;
}
else
{
newSize = sz;
}
if (newSize <= 0)
{
newSize = 1;
}
newArray = new vtkPriorityQueue::Item[newSize];
if (this->Array)
{
memcpy(newArray, this->Array,
(sz < this->Size ? sz : this->Size) * sizeof(vtkPriorityQueue::Item));
delete [] this->Array;
}
this->Size = newSize;
this->Array = newArray;
return this->Array;
}
// Reset all of the entries in the queue so they don not have a priority
void vtkPriorityQueue::Reset()
{
this->MaxId = -1;
for (int i=0; i <= this->ItemLocation->GetMaxId(); i++)
{
this->ItemLocation->SetValue(i,-1);
}
this->ItemLocation->Reset();
}
void vtkPriorityQueue::PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf(os,indent);
os << indent << "Number Of Entries: " << this->MaxId + 1 << "\n";
os << indent << "Size: " << this->Size << "\n";
os << indent << "Extend size: " << this->Extend << "\n";
}