zeek/src/Queue.cc
2011-08-04 15:21:18 -05:00

137 lines
2.1 KiB
C++

// See the file "COPYING" in the main distribution directory for copyright.
#include "config.h"
#include <string.h>
#include "Queue.h"
BaseQueue::BaseQueue(int size)
{
const int DEFAULT_CHUNK_SIZE = 10;
chunk_size = DEFAULT_CHUNK_SIZE;
head = tail = num_entries = 0;
if ( size < 0 )
{
entry = new ent[1];
max_entries = 0;
}
else
{
if ( (entry = new ent[chunk_size+1]) )
max_entries = chunk_size;
else
{
entry = new ent[1];
max_entries = 0;
}
}
}
void BaseQueue::push_front(ent a)
{
if ( num_entries == max_entries )
{
resize(max_entries+chunk_size); // make more room
chunk_size *= 2;
}
++num_entries;
if ( head )
entry[--head] = a;
else
{
head = max_entries;
entry[head] = a;
}
}
void BaseQueue::push_back(ent a)
{
if ( num_entries == max_entries )
{
resize(max_entries+chunk_size); // make more room
chunk_size *= 2;
}
++num_entries;
if ( tail < max_entries )
entry[tail++] = a;
else
{
entry[tail] = a;
tail = 0;
}
}
ent BaseQueue::pop_front()
{
if ( ! num_entries )
return 0;
--num_entries;
if ( head < max_entries )
return entry[head++];
else
{
head = 0;
return entry[max_entries];
}
}
ent BaseQueue::pop_back()
{
if ( ! num_entries )
return 0;
--num_entries;
if ( tail )
return entry[--tail];
else
{
tail = max_entries;
return entry[tail];
}
}
int BaseQueue::resize(int new_size)
{
if ( new_size < num_entries )
new_size = num_entries; // do not lose any entries
if ( new_size != max_entries )
{
// Note, allocate extra space, so that we can always
// use the [max_entries] element.
// ### Yin, why not use realloc()?
ent* new_entry = new ent[new_size+1];
if ( new_entry )
{
if ( head <= tail )
memcpy( new_entry, entry + head,
sizeof(ent) * num_entries );
else
{
int len = num_entries - tail;
memcpy( new_entry, entry + head,
sizeof(ent) * len );
memcpy( new_entry + len, entry,
sizeof(ent) * tail );
}
delete [] entry;
entry = new_entry;
max_entries = new_size;
head = 0;
tail = num_entries;
}
else
{ // out of memory
}
}
return max_entries;
}