Imported existing code
This commit is contained in:
315
indra/llcommon/lllinkedqueue.h
Normal file
315
indra/llcommon/lllinkedqueue.h
Normal file
@@ -0,0 +1,315 @@
|
||||
/**
|
||||
* @file lllinkedqueue.h
|
||||
* @brief Declaration of linked queue classes.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2003&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2003-2009, Linden Research, Inc.
|
||||
*
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLLINKEDQUEUE_H
|
||||
#define LL_LLLINKEDQUEUE_H
|
||||
|
||||
#include "llerror.h"
|
||||
|
||||
// node that actually contains the data
|
||||
template <class DATA_TYPE> class LLLinkedQueueNode
|
||||
{
|
||||
public:
|
||||
DATA_TYPE mData;
|
||||
LLLinkedQueueNode *mNextp;
|
||||
LLLinkedQueueNode *mPrevp;
|
||||
|
||||
|
||||
public:
|
||||
LLLinkedQueueNode();
|
||||
LLLinkedQueueNode(const DATA_TYPE data);
|
||||
|
||||
// destructor does not, by default, destroy associated data
|
||||
// however, the mDatap must be NULL to ensure that we aren't causing memory leaks
|
||||
~LLLinkedQueueNode();
|
||||
};
|
||||
|
||||
|
||||
|
||||
template <class DATA_TYPE> class LLLinkedQueue
|
||||
{
|
||||
|
||||
public:
|
||||
LLLinkedQueue();
|
||||
|
||||
// destructor destroys list and nodes, but not data in nodes
|
||||
~LLLinkedQueue();
|
||||
|
||||
// Puts at end of FIFO
|
||||
void push(const DATA_TYPE data);
|
||||
|
||||
// Takes off front of FIFO
|
||||
BOOL pop(DATA_TYPE &data);
|
||||
BOOL peek(DATA_TYPE &data);
|
||||
|
||||
void reset();
|
||||
|
||||
S32 getLength() const;
|
||||
|
||||
BOOL isEmpty() const;
|
||||
|
||||
BOOL remove(const DATA_TYPE data);
|
||||
|
||||
BOOL checkData(const DATA_TYPE data) const;
|
||||
|
||||
private:
|
||||
// add node to end of list
|
||||
// set mCurrentp to mQueuep
|
||||
void addNodeAtEnd(LLLinkedQueueNode<DATA_TYPE> *nodep);
|
||||
|
||||
private:
|
||||
LLLinkedQueueNode<DATA_TYPE> mHead; // head node
|
||||
LLLinkedQueueNode<DATA_TYPE> mTail; // tail node
|
||||
S32 mLength;
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// Nodes
|
||||
//
|
||||
|
||||
template <class DATA_TYPE>
|
||||
LLLinkedQueueNode<DATA_TYPE>::LLLinkedQueueNode() :
|
||||
mData(), mNextp(NULL), mPrevp(NULL)
|
||||
{ }
|
||||
|
||||
template <class DATA_TYPE>
|
||||
LLLinkedQueueNode<DATA_TYPE>::LLLinkedQueueNode(const DATA_TYPE data) :
|
||||
mData(data), mNextp(NULL), mPrevp(NULL)
|
||||
{ }
|
||||
|
||||
template <class DATA_TYPE>
|
||||
LLLinkedQueueNode<DATA_TYPE>::~LLLinkedQueueNode()
|
||||
{ }
|
||||
|
||||
|
||||
//
|
||||
// Queue itself
|
||||
//
|
||||
|
||||
template <class DATA_TYPE>
|
||||
LLLinkedQueue<DATA_TYPE>::LLLinkedQueue()
|
||||
: mHead(),
|
||||
mTail(),
|
||||
mLength(0)
|
||||
{ }
|
||||
|
||||
|
||||
// destructor destroys list and nodes, but not data in nodes
|
||||
template <class DATA_TYPE>
|
||||
LLLinkedQueue<DATA_TYPE>::~LLLinkedQueue()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
|
||||
// put data into a node and stick it at the end of the list
|
||||
template <class DATA_TYPE>
|
||||
void LLLinkedQueue<DATA_TYPE>::push(const DATA_TYPE data)
|
||||
{
|
||||
// make the new node
|
||||
LLLinkedQueueNode<DATA_TYPE> *nodep = new LLLinkedQueueNode<DATA_TYPE>(data);
|
||||
|
||||
addNodeAtEnd(nodep);
|
||||
}
|
||||
|
||||
|
||||
// search the list starting at mHead.mNextp and remove the link with mDatap == data
|
||||
// set mCurrentp to mQueuep, or NULL if mQueuep points to node with mDatap == data
|
||||
// return TRUE if found, FALSE if not found
|
||||
template <class DATA_TYPE>
|
||||
BOOL LLLinkedQueue<DATA_TYPE>::remove(const DATA_TYPE data)
|
||||
{
|
||||
BOOL b_found = FALSE;
|
||||
|
||||
LLLinkedQueueNode<DATA_TYPE> *currentp = mHead.mNextp;
|
||||
|
||||
while (currentp)
|
||||
{
|
||||
if (currentp->mData == data)
|
||||
{
|
||||
b_found = TRUE;
|
||||
|
||||
// if there is a next one, fix it
|
||||
if (currentp->mNextp)
|
||||
{
|
||||
currentp->mNextp->mPrevp = currentp->mPrevp;
|
||||
}
|
||||
else // we are at end of list
|
||||
{
|
||||
mTail.mPrevp = currentp->mPrevp;
|
||||
}
|
||||
|
||||
// if there is a previous one, fix it
|
||||
if (currentp->mPrevp)
|
||||
{
|
||||
currentp->mPrevp->mNextp = currentp->mNextp;
|
||||
}
|
||||
else // we are at beginning of list
|
||||
{
|
||||
mHead.mNextp = currentp->mNextp;
|
||||
}
|
||||
|
||||
// remove the node
|
||||
delete currentp;
|
||||
mLength--;
|
||||
break;
|
||||
}
|
||||
currentp = currentp->mNextp;
|
||||
}
|
||||
|
||||
return b_found;
|
||||
}
|
||||
|
||||
|
||||
// remove all nodes from the list but do not delete associated data
|
||||
template <class DATA_TYPE>
|
||||
void LLLinkedQueue<DATA_TYPE>::reset()
|
||||
{
|
||||
LLLinkedQueueNode<DATA_TYPE> *currentp;
|
||||
LLLinkedQueueNode<DATA_TYPE> *nextp;
|
||||
currentp = mHead.mNextp;
|
||||
|
||||
while (currentp)
|
||||
{
|
||||
nextp = currentp->mNextp;
|
||||
delete currentp;
|
||||
currentp = nextp;
|
||||
}
|
||||
|
||||
// reset mHead and mCurrentp
|
||||
mHead.mNextp = NULL;
|
||||
mTail.mPrevp = NULL;
|
||||
mLength = 0;
|
||||
}
|
||||
|
||||
template <class DATA_TYPE>
|
||||
S32 LLLinkedQueue<DATA_TYPE>::getLength() const
|
||||
{
|
||||
return mLength;
|
||||
}
|
||||
|
||||
template <class DATA_TYPE>
|
||||
BOOL LLLinkedQueue<DATA_TYPE>::isEmpty() const
|
||||
{
|
||||
return mLength <= 0;
|
||||
}
|
||||
|
||||
// check to see if data is in list
|
||||
// set mCurrentp and mQueuep to the target of search if found, otherwise set mCurrentp to mQueuep
|
||||
// return TRUE if found, FALSE if not found
|
||||
template <class DATA_TYPE>
|
||||
BOOL LLLinkedQueue<DATA_TYPE>::checkData(const DATA_TYPE data) const
|
||||
{
|
||||
LLLinkedQueueNode<DATA_TYPE> *currentp = mHead.mNextp;
|
||||
|
||||
while (currentp)
|
||||
{
|
||||
if (currentp->mData == data)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
currentp = currentp->mNextp;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
template <class DATA_TYPE>
|
||||
BOOL LLLinkedQueue<DATA_TYPE>::pop(DATA_TYPE &data)
|
||||
{
|
||||
LLLinkedQueueNode<DATA_TYPE> *currentp;
|
||||
|
||||
currentp = mHead.mNextp;
|
||||
if (!currentp)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
mHead.mNextp = currentp->mNextp;
|
||||
if (currentp->mNextp)
|
||||
{
|
||||
currentp->mNextp->mPrevp = currentp->mPrevp;
|
||||
}
|
||||
else
|
||||
{
|
||||
mTail.mPrevp = currentp->mPrevp;
|
||||
}
|
||||
|
||||
data = currentp->mData;
|
||||
delete currentp;
|
||||
mLength--;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
template <class DATA_TYPE>
|
||||
BOOL LLLinkedQueue<DATA_TYPE>::peek(DATA_TYPE &data)
|
||||
{
|
||||
LLLinkedQueueNode<DATA_TYPE> *currentp;
|
||||
|
||||
currentp = mHead.mNextp;
|
||||
if (!currentp)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
data = currentp->mData;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// private members
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
// add node to end of list
|
||||
// set mCurrentp to mQueuep
|
||||
template <class DATA_TYPE>
|
||||
void LLLinkedQueue<DATA_TYPE>::addNodeAtEnd(LLLinkedQueueNode<DATA_TYPE> *nodep)
|
||||
{
|
||||
// add the node to the end of the list
|
||||
nodep->mNextp = NULL;
|
||||
nodep->mPrevp = mTail.mPrevp;
|
||||
mTail.mPrevp = nodep;
|
||||
|
||||
// if there's something in the list, fix its back pointer
|
||||
if (nodep->mPrevp)
|
||||
{
|
||||
nodep->mPrevp->mNextp = nodep;
|
||||
}
|
||||
else // otherwise fix the head node
|
||||
{
|
||||
mHead.mNextp = nodep;
|
||||
}
|
||||
mLength++;
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user