zeek/src/PriorityQueue.cc
Robin Sommer 789cb376fd GH-239: Rename bro to zeek, bro-config to zeek-config, and bro-path-dev to zeek-path-dev.
This also installs symlinks from "zeek" and "bro-config" to a wrapper
script that prints a deprecation warning.

The btests pass, but this is still WIP. broctl renaming is still
missing.

#239
2019-05-01 21:43:45 +00:00

139 lines
2.2 KiB
C++

// See the file "COPYING" in the main distribution directory for copyright.
#include "zeek-config.h"
#include <stdio.h>
#include <stdlib.h>
#include "PriorityQueue.h"
#include "Reporter.h"
#include "util.h"
PriorityQueue::PriorityQueue(int initial_size)
{
max_heap_size = initial_size;
heap = new PQ_Element*[max_heap_size];
peak_heap_size = heap_size = cumulative_num = 0;
}
PriorityQueue::~PriorityQueue()
{
for ( int i = 0; i < heap_size; ++i )
delete heap[i];
delete [] heap;
}
PQ_Element* PriorityQueue::Remove()
{
if ( heap_size == 0 )
return 0;
PQ_Element* top = heap[0];
--heap_size;
SetElement(0, heap[heap_size]);
BubbleDown(0);
top->SetOffset(-1); // = not in heap
return top;
}
PQ_Element* PriorityQueue::Remove(PQ_Element* e)
{
if ( e->Offset() < 0 || e->Offset() >= heap_size ||
heap[e->Offset()] != e )
return 0; // not in heap
e->MinimizeTime();
BubbleUp(e->Offset());
PQ_Element* e2 = Remove();
if ( e != e2 )
reporter->InternalError("inconsistency in PriorityQueue::Remove");
return e2;
}
int PriorityQueue::Add(PQ_Element* e)
{
SetElement(heap_size, e);
BubbleUp(heap_size);
++cumulative_num;
if ( ++heap_size > peak_heap_size )
peak_heap_size = heap_size;
if ( heap_size >= max_heap_size )
return Resize(max_heap_size * 2);
else
return 1;
}
int PriorityQueue::Resize(int new_size)
{
PQ_Element** tmp = new PQ_Element*[new_size];
for ( int i = 0; i < max_heap_size; ++i )
tmp[i] = heap[i];
delete [] heap;
heap = tmp;
max_heap_size = new_size;
return heap != 0;
}
void PriorityQueue::BubbleUp(int bin)
{
if ( bin == 0 )
return;
int p = Parent(bin);
if ( heap[p]->Time() > heap[bin]->Time() )
{
Swap(p, bin);
BubbleUp(p);
}
}
void PriorityQueue::BubbleDown(int bin)
{
double v = heap[bin]->Time();
int l = LeftChild(bin);
int r = RightChild(bin);
if ( l >= heap_size )
return; // No children.
if ( r >= heap_size )
{ // Just a left child.
if ( heap[l]->Time() < v )
Swap(l, bin);
}
else
{
double lv = heap[l]->Time();
double rv = heap[r]->Time();
if ( lv < rv )
{
if ( lv < v )
{
Swap(l, bin);
BubbleDown(l);
}
}
else if ( rv < v )
{
Swap(r, bin);
BubbleDown(r);
}
}
}