zeek/src/PriorityQueue.cc
Robin Sommer 00d94f1bbc Merge remote-tracking branch 'origin/topic/seth/stats-improvement'
(Cleaned up some code a little bit.)

* origin/topic/seth/stats-improvement:
  Fixing tests for stats improvements
  Rename the reporting interval variable for stats.
  Removing more broken functionality due to changed stats apis.
  Removing some references to resource_usage()
  Removing Broker stats, it was broken and incomplete.
  Fixing default stats collection interval to every 5 minutes.
  Add DNS stats to the stats.log
  Small stats script tweaks and beginning broker stats.
  Continued stats cleanup and extension.
  More stats collection extensions.
  More stats improvements
  Slight change to Mach API for collecting memory usage.
  Fixing some small mistakes.
  Updating the cmake submodule for the stats updates.
  Fix memory usage collection on Mac OS X.
  Cleaned up stats collection.

BIT-1581 #merged
2016-05-07 11:51:35 -07:00

139 lines
2.2 KiB
C++

// See the file "COPYING" in the main distribution directory for copyright.
#include "bro-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);
}
}
}