#include "protoQueue.h"
ProtoQueue::ProtoQueue(bool usePool)
: container_pool(usePool ? &builtin_container_pool : NULL)
{
}
ProtoQueue::ProtoQueue(ContainerPool* containerPool)
: container_pool(containerPool)
{
}
ProtoQueue::~ProtoQueue()
{
builtin_container_pool.Destroy();
}
ProtoQueue::Container::Container()
: item(NULL), queue(NULL), entry(*this)
{
}
ProtoQueue::Container::~Container()
{
Cleanup();
}
void ProtoQueue::Container::Cleanup()
{
if (NULL != item)
{
ASSERT(NULL != queue);
queue->Remove(*item);
}
}
ProtoQueue::Container::Entry::Entry(Container& theContainer)
: container(theContainer)
{
}
ProtoQueue::Item::Item()
{
}
ProtoQueue::Item::~Item()
{
Cleanup();
}
void ProtoQueue::Item::Cleanup()
{
while (!container_list.IsEmpty())
{
Container::Entry*entry = static_cast<Container::Entry*>(container_list.GetRoot());
ProtoQueue* theQueue = entry->GetContainer().GetQueue();
ASSERT(NULL != theQueue);
theQueue->Remove(*this);
}
}
bool ProtoQueue::Item::IsInOtherQueue(const ProtoQueue& queue)
{
ProtoTree::Iterator iterator(container_list);
const ProtoQueue::Container::Entry* entry;
while (NULL != (entry = static_cast<const Container::Entry*>(iterator.GetNextItem())))
{
if (&queue != entry->GetContainer().GetQueue())
return true;
}
return false;
}
ProtoQueue::ContainerPool::ContainerPool()
{
}
ProtoQueue::ContainerPool::~ContainerPool()
{
Destroy();
}
void ProtoQueue::ContainerPool::Destroy()
{
Container* container;
while (NULL != (container = Get()))
delete container;
}
ProtoSimpleQueue::ProtoSimpleQueue(bool usePool)
: ProtoQueue(usePool)
{
}
ProtoSimpleQueue::ProtoSimpleQueue(ContainerPool* containerPool)
: ProtoQueue(containerPool)
{
}
ProtoSimpleQueue::~ProtoSimpleQueue()
{
Empty();
}
bool ProtoSimpleQueue::Append(Item& theItem)
{
Container* theContainer = GetContainerFromPool();
if (NULL == theContainer) theContainer = CreateContainer();
if (NULL == theContainer) return false;
Associate(theItem, *theContainer);
item_list.Append(*theContainer);
return true;
}
bool ProtoSimpleQueue::Prepend(ProtoQueue::Item& theItem)
{
Container* theContainer = GetContainerFromPool();
if (NULL == theContainer) theContainer = CreateContainer();
if (NULL == theContainer) return false;
Associate(theItem, *theContainer);
item_list.Prepend(*theContainer);
return true;
}
bool ProtoSimpleQueue::Insert(ProtoQueue::Item& theItem, ProtoQueue::Item& nextItem)
{
Container* theContainer = GetContainerFromPool();
if (NULL == theContainer) theContainer = CreateContainer();
if (NULL == theContainer) return false;
Associate(theItem, *theContainer);
Container* nextContainer = static_cast<Container*>(nextItem.GetContainer(*this));
if (NULL == nextContainer)
{
PLOG(PL_ERROR, "ProtoSimpleQueue::Insert() error: nextItem not in this queue?!\n");
Disassociate(theItem, *theContainer);
if (NULL != container_pool)
container_pool->Put(*theContainer);
else
delete theContainer;
return false;
}
item_list.Insert(*theContainer, *nextContainer);
return true;
}
bool ProtoSimpleQueue::InsertAfter(ProtoQueue::Item& theItem, ProtoQueue::Item& nextItem)
{
Container* theContainer = GetContainerFromPool();
if (NULL == theContainer) theContainer = CreateContainer();
if (NULL == theContainer) return false;
Associate(theItem, *theContainer);
Container* nextContainer = static_cast<Container*>(nextItem.GetContainer(*this));
if (NULL == nextContainer)
{
PLOG(PL_ERROR, "ProtoSimpleQueue::Insert() error: nextItem not in this queue?!\n");
Disassociate(theItem, *theContainer);
if (NULL != container_pool)
container_pool->Put(*theContainer);
else
delete theContainer;
return false;
}
item_list.InsertAfter(*theContainer, *nextContainer);
return true;
}
void ProtoSimpleQueue::Remove(Item& theItem)
{
Container* theContainer = static_cast<Container*>(ProtoQueue::GetContainer(theItem));
if (NULL != theContainer) RemoveContainer(theContainer, theItem);
}
ProtoSimpleQueue::Item* ProtoSimpleQueue::RemoveHead()
{
Container* container = item_list.GetHead();
if (NULL != container)
{
Item* item = container->GetItem();
ASSERT(NULL != item);
RemoveContainer(container, *item);
return item;
}
else
{
return NULL;
}
}
ProtoSimpleQueue::Item* ProtoSimpleQueue::RemoveTail()
{
Container* container = item_list.GetTail();
if (NULL != container)
{
Item* item = container->GetItem();
ASSERT(NULL != item);
RemoveContainer(container, *item);
return item;
}
else
{
return NULL;
}
}
void ProtoSimpleQueue::RemoveContainer(Container* theContainer, Item& theItem)
{
ASSERT(NULL != theContainer);
item_list.Remove(*theContainer);
Disassociate(theItem, *theContainer);
if (NULL != container_pool)
container_pool->Put(*theContainer);
else
delete theContainer;
}
void ProtoSimpleQueue::Empty()
{
Container* nextContainer;
while (NULL != (nextContainer = item_list.RemoveHead()))
{
ProtoQueue::Item* nextItem = nextContainer->GetItem();
ASSERT(NULL != nextItem);
Disassociate(*nextItem, *nextContainer);
if (NULL != container_pool)
container_pool->Put(*nextContainer);
else
delete nextContainer;
}
}
void ProtoSimpleQueue::Destroy()
{
Container* nextContainer;
while (NULL != (nextContainer = item_list.RemoveHead()))
{
ProtoQueue::Item* nextItem = nextContainer->GetItem();
ASSERT(NULL != nextItem);
Disassociate(*nextItem, *nextContainer);
delete nextItem;
if (NULL != container_pool)
container_pool->Put(*nextContainer);
else
delete nextContainer;
}
}
ProtoSimpleQueue::Iterator::Iterator(ProtoSimpleQueue& theQueue, bool reverse)
: ProtoList::Iterator(theQueue.item_list, reverse)
{
}
ProtoSimpleQueue::Iterator::~Iterator()
{
}
ProtoSimpleQueue::Container::Container()
{
}
ProtoSimpleQueue::Container::~Container()
{
Cleanup();
}
ProtoIndexedQueue::ProtoIndexedQueue(bool usePool)
: ProtoQueue(usePool)
{
}
ProtoIndexedQueue::ProtoIndexedQueue(ContainerPool* containerPool)
: ProtoQueue(containerPool)
{
}
ProtoIndexedQueue::~ProtoIndexedQueue()
{
Empty();
}
bool ProtoIndexedQueue::Insert(Item& theItem)
{
Container* theContainer = GetContainerFromPool();
if (NULL == theContainer) theContainer = CreateContainer();
if (NULL == theContainer) return false;
Associate(theItem, *theContainer);
item_tree.Insert(*theContainer);
return true;
}
void ProtoIndexedQueue::Remove(Item& theItem)
{
Container* theContainer = static_cast<Container*>(ProtoQueue::GetContainer(theItem));
if (NULL != theContainer)
{
item_tree.Remove(*theContainer);
Disassociate(theItem, *theContainer);
if (NULL != container_pool)
container_pool->Put(*theContainer);
else
delete theContainer;
}
}
void ProtoIndexedQueue::Empty()
{
Container* nextContainer;
Tree::SimpleIterator sit(item_tree);
ContainerPool tmpPool;
while (NULL != (nextContainer = sit.GetNextItem()))
{
ProtoQueue::Item* nextItem = nextContainer->GetItem();
ASSERT(NULL != nextItem);
Disassociate(*nextItem, *nextContainer);
if (NULL != container_pool)
container_pool->Put(*nextContainer);
else
tmpPool.Put(*nextContainer);
}
tmpPool.Destroy();
item_tree.Empty(); }
void ProtoIndexedQueue::Destroy()
{
Container* nextContainer;
Tree::SimpleIterator sit(item_tree);
ContainerPool tmpPool;
while (NULL != (nextContainer = sit.GetNextItem()))
{
ProtoQueue::Item* nextItem = nextContainer->GetItem();
ASSERT(NULL != nextItem);
Disassociate(*nextItem, *nextContainer);
delete nextItem;
if (NULL != container_pool)
container_pool->Put(*nextContainer);
else
tmpPool.Put(*nextContainer);
}
tmpPool.Destroy();
item_tree.Empty(); }
ProtoIndexedQueue::Iterator::Iterator(ProtoIndexedQueue& theQueue, bool reverse)
: ProtoTree::Iterator(theQueue.item_tree, reverse)
{
}
ProtoIndexedQueue::Iterator::~Iterator()
{
}
ProtoIndexedQueue::Container::Container()
{
}
ProtoIndexedQueue::Container::~Container()
{
Cleanup();
}
const char* ProtoIndexedQueue::Container::GetKey() const
{
ProtoQueue::Item* item = GetItem();
ASSERT(NULL != item);
ProtoIndexedQueue* iq = static_cast<ProtoIndexedQueue*>(GetQueue());
return (iq->GetKey(*item));
}
unsigned int ProtoIndexedQueue::Container::GetKeysize() const
{
ProtoQueue::Item* item = GetItem();
ASSERT(NULL != item);
ProtoIndexedQueue* iq = static_cast<ProtoIndexedQueue*>(GetQueue());
return (iq->GetKeysize(*item));
}
ProtoSortedQueue::ProtoSortedQueue(bool usePool)
: ProtoQueue(usePool)
{
}
ProtoSortedQueue::ProtoSortedQueue(ContainerPool* containerPool)
: ProtoQueue(containerPool)
{
}
ProtoSortedQueue::~ProtoSortedQueue()
{
Empty();
}
bool ProtoSortedQueue::Insert(Item& theItem)
{
Container* theContainer = GetContainerFromPool();
if (NULL == theContainer) theContainer = CreateContainer();
if (NULL == theContainer) return false;
Associate(theItem, *theContainer);
item_tree.Insert(*theContainer);
return true;
}
void ProtoSortedQueue::Remove(Item& theItem)
{
Container* theContainer = static_cast<Container*>(ProtoQueue::GetContainer(theItem));
if (NULL != theContainer)
{
item_tree.Remove(*theContainer);
Disassociate(theItem, *theContainer);
if (NULL != container_pool)
container_pool->Put(*theContainer);
else
delete theContainer;
}
}
void ProtoSortedQueue::Empty()
{
Container* nextContainer;
ProtoSortedTree::Iterator iterator(item_tree);
while (NULL != (nextContainer = static_cast<Container*>(iterator.GetNextItem())))
{
ProtoQueue::Item* nextItem = nextContainer->GetItem();
ASSERT(NULL != nextItem);
Disassociate(*nextItem, *nextContainer);
if (NULL != container_pool)
container_pool->Put(*nextContainer);
else
delete nextContainer;
}
item_tree.Empty();
}
void ProtoSortedQueue::Destroy()
{
Container* nextContainer;
ProtoSortedTree::Iterator iterator(item_tree);
while (NULL != (nextContainer = static_cast<Container*>(iterator.GetNextItem())))
{
ProtoQueue::Item* nextItem = nextContainer->GetItem();
ASSERT(NULL != nextItem);
Disassociate(*nextItem, *nextContainer);
delete nextItem;
if (NULL != container_pool)
container_pool->Put(*nextContainer);
else
delete nextContainer;
}
item_tree.Empty();
}
ProtoTree::Endian ProtoSortedQueue::GetEndian() const
{
return ProtoTree::ENDIAN_BIG; }
bool ProtoSortedQueue::UseComplement2() const
{
return true;
}
bool ProtoSortedQueue::UseSignBit() const
{
return false;
}
ProtoSortedQueue::Iterator::Iterator(ProtoSortedQueue& theQueue,
bool reverse,
const char* keyMin,
unsigned int keysize)
: ProtoSortedTree::Iterator(theQueue.item_tree, reverse, keyMin, keysize)
{
}
ProtoSortedQueue::Iterator::~Iterator()
{
}
ProtoSortedQueue::Container::Container()
{
}
ProtoSortedQueue::Container::~Container()
{
Cleanup();
}
const char* ProtoSortedQueue::Container::GetKey() const
{
ProtoQueue::Item* item = GetItem();
ASSERT(NULL != item);
ProtoSortedQueue* sq = static_cast<ProtoSortedQueue*>(GetQueue());
return (sq->GetKey(*item));
}
unsigned int ProtoSortedQueue::Container::GetKeysize() const
{
ProtoQueue::Item* item = GetItem();
ASSERT(NULL != item);
ProtoSortedQueue* sq = static_cast<ProtoSortedQueue*>(GetQueue());
return (sq->GetKeysize(*item));
}
ProtoTree::Endian ProtoSortedQueue::Container::GetEndian() const
{
ProtoSortedQueue* sq = static_cast<ProtoSortedQueue*>(GetQueue());
ASSERT(NULL != sq);
return (sq->GetEndian());
}
bool ProtoSortedQueue::Container::UseComplement2() const
{
ProtoSortedQueue* sq = static_cast<ProtoSortedQueue*>(GetQueue());
ASSERT(NULL != sq);
return (sq->UseComplement2());
}
bool ProtoSortedQueue::Container::UseSignBit() const
{
ProtoSortedQueue* sq = static_cast<ProtoSortedQueue*>(GetQueue());
ASSERT(NULL != sq);
return (sq->UseSignBit());
}