llptrskipmap.h
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:28k
- /**
- * @file llptrskipmap.h
- * @brief Just like a LLSkipMap, but since it's pointers, you can call
- * deleteAllData
- *
- * $LicenseInfo:firstyear=2003&license=viewergpl$
- *
- * Copyright (c) 2003-2010, 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_LLPTRSKIPMAP_H
- #define LL_LLPTRSKIPMAP_H
- #include "llerror.h"
- #include "llrand.h"
- template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH = 8>
- class LLPtrSkipMapNode
- {
- public:
- LLPtrSkipMapNode()
- {
- S32 i;
- for (i = 0; i < BINARY_DEPTH; i++)
- {
- mForward[i] = NULL;
- }
- U8 *zero = (U8 *)&mIndex;
- for (i = 0; i < (S32)sizeof(INDEX_T); i++)
- {
- *(zero + i) = 0;
- }
- zero = (U8 *)&mData;
- for (i = 0; i < (S32)sizeof(DATA_T); i++)
- {
- *(zero + i) = 0;
- }
- }
- LLPtrSkipMapNode(const INDEX_T &index)
- : mIndex(index)
- {
- S32 i;
- for (i = 0; i < BINARY_DEPTH; i++)
- {
- mForward[i] = NULL;
- }
- U8 *zero = (U8 *)&mData;
- for (i = 0; i < (S32)sizeof(DATA_T); i++)
- {
- *(zero + i) = 0;
- }
- }
- LLPtrSkipMapNode(const INDEX_T &index, DATA_T datap)
- : mIndex(index)
- {
- S32 i;
- for (i = 0; i < BINARY_DEPTH; i++)
- {
- mForward[i] = NULL;
- }
- mData = datap;
- }
- ~LLPtrSkipMapNode()
- {
- }
- // delete associated data and NULLs out pointer
- void deleteData()
- {
- delete mData;
- mData = 0;
- }
- // NULLs out pointer
- void removeData()
- {
- mData = 0;
- }
- INDEX_T mIndex;
- DATA_T mData;
- LLPtrSkipMapNode *mForward[BINARY_DEPTH];
- private:
- // Disallow copying of LLPtrSkipMapNodes by not implementing these methods.
- LLPtrSkipMapNode(const LLPtrSkipMapNode &);
- LLPtrSkipMapNode &operator=(const LLPtrSkipMapNode &rhs);
- };
- //---------------------------------------------------------------------------
- template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH = 8>
- class LLPtrSkipMap
- {
- public:
- typedef BOOL (*compare)(const DATA_T& first, const DATA_T& second);
- typedef compare insert_func;
- typedef compare equals_func;
- void init();
- // basic constructor
- LLPtrSkipMap();
- // basic constructor including sorter
- LLPtrSkipMap(insert_func insert_first, equals_func equals);
- ~LLPtrSkipMap();
- void setInsertFirst(insert_func insert_first);
- void setEquals(equals_func equals);
- DATA_T &addData(const INDEX_T &index, DATA_T datap);
- DATA_T &addData(const INDEX_T &index);
- DATA_T &getData(const INDEX_T &index);
- DATA_T &operator[](const INDEX_T &index);
- // If index present, returns data.
- // If index not present, adds <index,NULL> and returns NULL.
- DATA_T &getData(const INDEX_T &index, BOOL &b_new_entry);
- // returns data entry before and after index
- BOOL getInterval(const INDEX_T &index, INDEX_T &index_before, INDEX_T &index_after,
- DATA_T &data_before, DATA_T &data_after );
- // Returns TRUE if data present in map.
- BOOL checkData(const INDEX_T &index);
- // Returns TRUE if key is present in map. This is useful if you
- // are potentially storing NULL pointers in the map
- BOOL checkKey(const INDEX_T &index);
- // If there, returns the data.
- // If not, returns NULL.
- // Never adds entries to the map.
- DATA_T getIfThere(const INDEX_T &index);
- INDEX_T reverseLookup(const DATA_T datap);
- // returns number of items in the list
- S32 getLength(); // WARNING! getLength is O(n), not O(1)!
- BOOL removeData(const INDEX_T &index);
- BOOL deleteData(const INDEX_T &index);
- // remove all nodes from the list but do not delete data
- void removeAllData();
- void deleteAllData();
- // place mCurrentp on first node
- void resetList();
- // return the data currently pointed to
- DATA_T getCurrentDataWithoutIncrement();
- // return the data currently pointed to, set mCurentOperatingp to that node and bump mCurrentp
- DATA_T getCurrentData();
- // same as getCurrentData() but a more intuitive name for the operation
- DATA_T getNextData();
- INDEX_T getNextKey();
- // return the key currently pointed to
- INDEX_T getCurrentKeyWithoutIncrement();
- // remove the Node at mCurentOperatingp
- // leave mCurrentp and mCurentOperatingp on the next entry
- void removeCurrentData();
- void deleteCurrentData();
- // reset the list and return the data currently pointed to, set mCurentOperatingp to that node and bump mCurrentp
- DATA_T getFirstData();
- INDEX_T getFirstKey();
- static BOOL defaultEquals(const INDEX_T &first, const INDEX_T &second)
- {
- return first == second;
- }
- private:
- // don't generate implicit copy constructor or copy assignment
- LLPtrSkipMap(const LLPtrSkipMap &);
- LLPtrSkipMap &operator=(const LLPtrSkipMap &);
- private:
- LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> mHead;
- LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *mUpdate[BINARY_DEPTH];
- LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *mCurrentp;
- LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *mCurrentOperatingp;
- S32 mLevel;
- BOOL (*mInsertFirst)(const INDEX_T &first, const INDEX_T &second);
- BOOL (*mEquals)(const INDEX_T &first, const INDEX_T &second);
- S32 mNumberOfSteps;
- };
- //////////////////////////////////////////////////
- //
- // LLPtrSkipMap implementation
- //
- //
- template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH>
- inline LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::LLPtrSkipMap()
- : mInsertFirst(NULL),
- mEquals(defaultEquals),
- mNumberOfSteps(0)
- {
- if (BINARY_DEPTH < 2)
- {
- llerrs << "Trying to create skip list with too little depth, "
- "must be 2 or greater" << llendl;
- }
- S32 i;
- for (i = 0; i < BINARY_DEPTH; i++)
- {
- mUpdate[i] = NULL;
- }
- mLevel = 1;
- mCurrentp = *(mHead.mForward);
- mCurrentOperatingp = *(mHead.mForward);
- }
- template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH>
- inline LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::LLPtrSkipMap(insert_func insert_first,
- equals_func equals)
- : mInsertFirst(insert_first),
- mEquals(equals),
- mNumberOfSteps(0)
- {
- if (BINARY_DEPTH < 2)
- {
- llerrs << "Trying to create skip list with too little depth, "
- "must be 2 or greater" << llendl;
- }
- mLevel = 1;
- S32 i;
- for (i = 0; i < BINARY_DEPTH; i++)
- {
- mHead.mForward[i] = NULL;
- mUpdate[i] = NULL;
- }
- mCurrentp = *(mHead.mForward);
- mCurrentOperatingp = *(mHead.mForward);
- }
- template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH>
- inline LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::~LLPtrSkipMap()
- {
- removeAllData();
- }
- template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH>
- inline void LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::setInsertFirst(insert_func insert_first)
- {
- mInsertFirst = insert_first;
- }
- template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH>
- inline void LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::setEquals(equals_func equals)
- {
- mEquals = equals;
- }
- template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH>
- inline DATA_T &LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::addData(const INDEX_T &index, DATA_T datap)
- {
- S32 level;
- LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *current = &mHead;
- LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *temp;
- // find the pointer one in front of the one we want
- if (mInsertFirst)
- {
- for (level = mLevel - 1; level >= 0; level--)
- {
- temp = *(current->mForward + level);
- while ( (temp)
- &&(mInsertFirst(temp->mIndex, index)))
- {
- current = temp;
- temp = *(current->mForward + level);
- }
- *(mUpdate + level) = current;
- }
- }
- else
- {
- for (level = mLevel - 1; level >= 0; level--)
- {
- temp = *(current->mForward + level);
- while ( (temp)
- &&(temp->mIndex < index))
- {
- current = temp;
- temp = *(current->mForward + level);
- }
- *(mUpdate + level) = current;
- }
- }
-
- // we're now just in front of where we want to be . . . take one step forward
- current = *current->mForward;
- // replace the existing data if a node is already there
- if ( (current)
- &&(mEquals(current->mIndex, index)))
- {
- current->mData = datap;
- return current->mData;
- }
- // now add the new node
- S32 newlevel;
- for (newlevel = 1; newlevel <= mLevel && newlevel < BINARY_DEPTH; newlevel++)
- {
- if (ll_frand() < 0.5f)
- {
- break;
- }
- }
- LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *snode
- = new LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH>(index, datap);
- if (newlevel > mLevel)
- {
- mHead.mForward[mLevel] = NULL;
- mUpdate[mLevel] = &mHead;
- mLevel = newlevel;
- }
- for (level = 0; level < newlevel; level++)
- {
- snode->mForward[level] = mUpdate[level]->mForward[level];
- mUpdate[level]->mForward[level] = snode;
- }
- return snode->mData;
- }
- template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH>
- inline DATA_T &LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::addData(const INDEX_T &index)
- {
- S32 level;
- LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *current = &mHead;
- LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *temp;
- // find the pointer one in front of the one we want
- if (mInsertFirst)
- {
- for (level = mLevel - 1; level >= 0; level--)
- {
- temp = *(current->mForward + level);
- while ( (temp)
- &&(mInsertFirst(temp->mIndex, index)))
- {
- current = temp;
- temp = *(current->mForward + level);
- }
- *(mUpdate + level) = current;
- }
- }
- else
- {
- for (level = mLevel - 1; level >= 0; level--)
- {
- temp = *(current->mForward + level);
- while ( (temp)
- &&(temp->mIndex < index))
- {
- current = temp;
- temp = *(current->mForward + level);
- }
- *(mUpdate + level) = current;
- }
- }
-
- // we're now just in front of where we want to be . . . take one step forward
- current = *current->mForward;
- // now add the new node
- S32 newlevel;
- for (newlevel = 1; newlevel <= mLevel && newlevel < BINARY_DEPTH; newlevel++)
- {
- if (ll_frand() < 0.5f)
- break;
- }
- LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *snode
- = new LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH>(index);
- if (newlevel > mLevel)
- {
- mHead.mForward[mLevel] = NULL;
- mUpdate[mLevel] = &mHead;
- mLevel = newlevel;
- }
- for (level = 0; level < newlevel; level++)
- {
- snode->mForward[level] = mUpdate[level]->mForward[level];
- mUpdate[level]->mForward[level] = snode;
- }
- return snode->mData;
- }
- template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH>
- inline DATA_T &LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::getData(const INDEX_T &index)
- {
- S32 level;
- LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *current = &mHead;
- LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *temp;
- mNumberOfSteps = 0;
- // find the pointer one in front of the one we want
- if (mInsertFirst)
- {
- for (level = mLevel - 1; level >= 0; level--)
- {
- temp = *(current->mForward + level);
- while ( (temp)
- &&(mInsertFirst(temp->mIndex, index)))
- {
- current = temp;
- temp = *(current->mForward + level);
- mNumberOfSteps++;
- }
- *(mUpdate + level) = current;
- }
- }
- else
- {
- for (level = mLevel - 1; level >= 0; level--)
- {
- temp = *(current->mForward + level);
- while ( (temp)
- &&(temp->mIndex < index))
- {
- current = temp;
- temp = *(current->mForward + level);
- mNumberOfSteps++;
- }
- *(mUpdate + level) = current;
- }
- }
-
- // we're now just in front of where we want to be . . . take one step forward
- current = *current->mForward;
- mNumberOfSteps++;
- if ( (current)
- &&(mEquals(current->mIndex, index)))
- {
-
- return current->mData;
- }
-
- // now add the new node
- S32 newlevel;
- for (newlevel = 1; newlevel <= mLevel && newlevel < BINARY_DEPTH; newlevel++)
- {
- if (ll_frand() < 0.5f)
- break;
- }
- LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *snode
- = new LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH>(index);
- if (newlevel > mLevel)
- {
- mHead.mForward[mLevel] = NULL;
- mUpdate[mLevel] = &mHead;
- mLevel = newlevel;
- }
- for (level = 0; level < newlevel; level++)
- {
- snode->mForward[level] = mUpdate[level]->mForward[level];
- mUpdate[level]->mForward[level] = snode;
- }
-
- return snode->mData;
- }
- template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH>
- inline BOOL LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::getInterval(const INDEX_T &index,
- INDEX_T &index_before,
- INDEX_T &index_after,
- DATA_T &data_before,
- DATA_T &data_after)
- {
- S32 level;
- LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *current = &mHead;
- LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *temp;
- mNumberOfSteps = 0;
- // find the pointer one in front of the one we want
- if (mInsertFirst)
- {
- for (level = mLevel - 1; level >= 0; level--)
- {
- temp = *(current->mForward + level);
- while ( (temp)
- &&(mInsertFirst(temp->mIndex, index)))
- {
- current = temp;
- temp = *(current->mForward + level);
- mNumberOfSteps++;
- }
- *(mUpdate + level) = current;
- }
- }
- else
- {
- for (level = mLevel - 1; level >= 0; level--)
- {
- temp = *(current->mForward + level);
- while ( (temp)
- &&(temp->mIndex < index))
- {
- current = temp;
- temp = *(current->mForward + level);
- mNumberOfSteps++;
- }
- *(mUpdate + level) = current;
- }
- }
-
- BOOL both_found = TRUE;
- if (current != &mHead)
- {
- index_before = current->mIndex;
- data_before = current->mData;
- }
- else
- {
- data_before = 0;
- index_before = 0;
- both_found = FALSE;
- }
- // we're now just in front of where we want to be . . . take one step forward
- mNumberOfSteps++;
- current = *current->mForward;
- if (current)
- {
- data_after = current->mData;
- index_after = current->mIndex;
- }
- else
- {
- data_after = 0;
- index_after = 0;
- both_found = FALSE;
- }
- return both_found;
- }
- template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH>
- inline DATA_T &LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::operator[](const INDEX_T &index)
- {
-
- return getData(index);
- }
- // If index present, returns data.
- // If index not present, adds <index,NULL> and returns NULL.
- template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH>
- inline DATA_T &LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::getData(const INDEX_T &index, BOOL &b_new_entry)
- {
- S32 level;
- LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *current = &mHead;
- LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *temp;
- mNumberOfSteps = 0;
- // find the pointer one in front of the one we want
- if (mInsertFirst)
- {
- for (level = mLevel - 1; level >= 0; level--)
- {
- temp = *(current->mForward + level);
- while ( (temp)
- &&(mInsertFirst(temp->mIndex, index)))
- {
- current = temp;
- temp = *(current->mForward + level);
- mNumberOfSteps++;
- }
- *(mUpdate + level) = current;
- }
- }
- else
- {
- for (level = mLevel - 1; level >= 0; level--)
- {
- temp = *(current->mForward + level);
- while ( (temp)
- &&(temp->mIndex < index))
- {
- current = temp;
- temp = *(current->mForward + level);
- mNumberOfSteps++;
- }
- *(mUpdate + level) = current;
- }
- }
-
- // we're now just in front of where we want to be . . . take one step forward
- mNumberOfSteps++;
- current = *current->mForward;
- if ( (current)
- &&(mEquals(current->mIndex, index)))
- {
-
- return current->mData;
- }
- b_new_entry = TRUE;
- addData(index);
-
- return current->mData;
- }
- // Returns TRUE if data present in map.
- template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH>
- inline BOOL LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::checkData(const INDEX_T &index)
- {
- S32 level;
- LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *current = &mHead;
- LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *temp;
- // find the pointer one in front of the one we want
- if (mInsertFirst)
- {
- for (level = mLevel - 1; level >= 0; level--)
- {
- temp = *(current->mForward + level);
- while ( (temp)
- &&(mInsertFirst(temp->mIndex, index)))
- {
- current = temp;
- temp = *(current->mForward + level);
- }
- *(mUpdate + level) = current;
- }
- }
- else
- {
- for (level = mLevel - 1; level >= 0; level--)
- {
- temp = *(current->mForward + level);
- while ( (temp)
- &&(temp->mIndex < index))
- {
- current = temp;
- temp = *(current->mForward + level);
- }
- *(mUpdate + level) = current;
- }
- }
-
- // we're now just in front of where we want to be . . . take one step forward
- current = *current->mForward;
- if (current)
- {
- // Gets rid of some compiler ambiguity for the LLPointer<> templated class.
- if (current->mData)
- {
- return mEquals(current->mIndex, index);
- }
- }
- return FALSE;
- }
- // Returns TRUE if key is present in map. This is useful if you
- // are potentially storing NULL pointers in the map
- template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH>
- inline BOOL LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::checkKey(const INDEX_T &index)
- {
- S32 level;
- LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *current = &mHead;
- LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *temp;
- // find the pointer one in front of the one we want
- if (mInsertFirst)
- {
- for (level = mLevel - 1; level >= 0; level--)
- {
- temp = *(current->mForward + level);
- while ( (temp)
- &&(mInsertFirst(temp->mIndex, index)))
- {
- current = temp;
- temp = *(current->mForward + level);
- }
- *(mUpdate + level) = current;
- }
- }
- else
- {
- for (level = mLevel - 1; level >= 0; level--)
- {
- temp = *(current->mForward + level);
- while ( (temp)
- &&(temp->mIndex < index))
- {
- current = temp;
- temp = *(current->mForward + level);
- }
- *(mUpdate + level) = current;
- }
- }
-
- // we're now just in front of where we want to be . . . take one step forward
- current = *current->mForward;
- if (current)
- {
- return mEquals(current->mIndex, index);
- }
- return FALSE;
- }
- // If there, returns the data.
- // If not, returns NULL.
- // Never adds entries to the map.
- template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH>
- inline DATA_T LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::getIfThere(const INDEX_T &index)
- {
- S32 level;
- LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *current = &mHead;
- LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *temp;
- mNumberOfSteps = 0;
- // find the pointer one in front of the one we want
- if (mInsertFirst)
- {
- for (level = mLevel - 1; level >= 0; level--)
- {
- temp = *(current->mForward + level);
- while ( (temp)
- &&(mInsertFirst(temp->mIndex, index)))
- {
- current = temp;
- temp = *(current->mForward + level);
- mNumberOfSteps++;
- }
- *(mUpdate + level) = current;
- }
- }
- else
- {
- for (level = mLevel - 1; level >= 0; level--)
- {
- temp = *(current->mForward + level);
- while ( (temp)
- &&(temp->mIndex < index))
- {
- current = temp;
- temp = *(current->mForward + level);
- mNumberOfSteps++;
- }
- *(mUpdate + level) = current;
- }
- }
-
- // we're now just in front of where we want to be . . . take one step forward
- mNumberOfSteps++;
- current = *current->mForward;
- if (current)
- {
- if (mEquals(current->mIndex, index))
- {
- return current->mData;
- }
- }
- // Avoid Linux compiler warning on returning NULL.
- return (DATA_T)0;
- }
- template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH>
- inline INDEX_T LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::reverseLookup(const DATA_T datap)
- {
- LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *current = &mHead;
- while (current)
- {
- if (datap == current->mData)
- {
-
- return current->mIndex;
- }
- current = *current->mForward;
- }
- // not found! return NULL
- return INDEX_T();
- }
- // returns number of items in the list
- template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH>
- inline S32 LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::getLength()
- {
- U32 length = 0;
- LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH>* temp;
- for (temp = *(mHead.mForward); temp != NULL; temp = temp->mForward[0])
- {
- length++;
- }
-
- return length;
- }
- template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH>
- inline BOOL LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::removeData(const INDEX_T &index)
- {
- S32 level;
- LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *current = &mHead;
- LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *temp;
- // find the pointer one in front of the one we want
- if (mInsertFirst)
- {
- for (level = mLevel - 1; level >= 0; level--)
- {
- temp = *(current->mForward + level);
- while ( (temp)
- &&(mInsertFirst(temp->mIndex, index)))
- {
- current = temp;
- temp = *(current->mForward + level);
- }
- *(mUpdate + level) = current;
- }
- }
- else
- {
- for (level = mLevel - 1; level >= 0; level--)
- {
- temp = *(current->mForward + level);
- while ( (temp)
- &&(temp->mIndex < index))
- {
- current = temp;
- temp = *(current->mForward + level);
- }
- *(mUpdate + level) = current;
- }
- }
-
- // we're now just in front of where we want to be . . . take one step forward
- current = *current->mForward;
- if (!current)
- {
- // empty list or beyond the end!
-
- return FALSE;
- }
- // is this the one we want?
- if (!mEquals(current->mIndex, index))
- {
- // nope!
-
- return FALSE;
- }
- else
- {
- // do we need to fix current or currentop?
- if (current == mCurrentp)
- {
- mCurrentp = *current->mForward;
- }
- if (current == mCurrentOperatingp)
- {
- mCurrentOperatingp = *current->mForward;
- }
- // yes it is! change pointers as required
- for (level = 0; level < mLevel; level++)
- {
- if (*((*(mUpdate + level))->mForward + level) != current)
- {
- // cool, we've fixed all the pointers!
- break;
- }
- *((*(mUpdate + level))->mForward + level) = *(current->mForward + level);
- }
- // clean up cuurent
- current->removeData();
- delete current;
- // clean up mHead
- while ( (mLevel > 1)
- &&(!*(mHead.mForward + mLevel - 1)))
- {
- mLevel--;
- }
- }
-
- return TRUE;
- }
- template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH>
- inline BOOL LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::deleteData(const INDEX_T &index)
- {
- S32 level;
- LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *current = &mHead;
- LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *temp;
- // find the pointer one in front of the one we want
- if (mInsertFirst)
- {
- for (level = mLevel - 1; level >= 0; level--)
- {
- temp = *(current->mForward + level);
- while ( (temp)
- &&(mInsertFirst(temp->mIndex, index)))
- {
- current = temp;
- temp = *(current->mForward + level);
- }
- *(mUpdate + level) = current;
- }
- }
- else
- {
- for (level = mLevel - 1; level >= 0; level--)
- {
- temp = *(current->mForward + level);
- while ( (temp)
- &&(temp->mIndex < index))
- {
- current = temp;
- temp = *(current->mForward + level);
- }
- *(mUpdate + level) = current;
- }
- }
-
- // we're now just in front of where we want to be . . . take one step forward
- current = *current->mForward;
- if (!current)
- {
- // empty list or beyond the end!
-
- return FALSE;
- }
- // is this the one we want?
- if (!mEquals(current->mIndex, index))
- {
- // nope!
-
- return FALSE;
- }
- else
- {
- // do we need to fix current or currentop?
- if (current == mCurrentp)
- {
- mCurrentp = *current->mForward;
- }
- if (current == mCurrentOperatingp)
- {
- mCurrentOperatingp = *current->mForward;
- }
- // yes it is! change pointers as required
- for (level = 0; level < mLevel; level++)
- {
- if (*((*(mUpdate + level))->mForward + level) != current)
- {
- // cool, we've fixed all the pointers!
- break;
- }
- *((*(mUpdate + level))->mForward + level) = *(current->mForward + level);
- }
- // clean up cuurent
- current->deleteData();
- delete current;
- // clean up mHead
- while ( (mLevel > 1)
- &&(!*(mHead.mForward + mLevel - 1)))
- {
- mLevel--;
- }
- }
-
- return TRUE;
- }
- // remove all nodes from the list but do not delete data
- template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH>
- void LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::removeAllData()
- {
- LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *temp;
- // reset mCurrentp
- mCurrentp = *(mHead.mForward);
- while (mCurrentp)
- {
- temp = mCurrentp->mForward[0];
- mCurrentp->removeData();
- delete mCurrentp;
- mCurrentp = temp;
- }
- S32 i;
- for (i = 0; i < BINARY_DEPTH; i++)
- {
- mHead.mForward[i] = NULL;
- mUpdate[i] = NULL;
- }
- mCurrentp = *(mHead.mForward);
- mCurrentOperatingp = *(mHead.mForward);
- }
- template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH>
- inline void LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::deleteAllData()
- {
- LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *temp;
- // reset mCurrentp
- mCurrentp = *(mHead.mForward);
- while (mCurrentp)
- {
- temp = mCurrentp->mForward[0];
- mCurrentp->deleteData();
- delete mCurrentp;
- mCurrentp = temp;
- }
- S32 i;
- for (i = 0; i < BINARY_DEPTH; i++)
- {
- mHead.mForward[i] = NULL;
- mUpdate[i] = NULL;
- }
- mCurrentp = *(mHead.mForward);
- mCurrentOperatingp = *(mHead.mForward);
- }
- // place mCurrentp on first node
- template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH>
- inline void LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::resetList()
- {
- mCurrentp = *(mHead.mForward);
- mCurrentOperatingp = *(mHead.mForward);
- }
- // return the data currently pointed to
- template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH>
- inline DATA_T LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::getCurrentDataWithoutIncrement()
- {
- if (mCurrentOperatingp)
- {
- return mCurrentOperatingp->mData;
- }
- else
- {
- //return NULL; // causes warning
- return (DATA_T)0; // equivalent, but no warning
- }
- }
- // return the data currently pointed to, set mCurentOperatingp to that node and bump mCurrentp
- template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH>
- inline DATA_T LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::getCurrentData()
- {
- if (mCurrentp)
- {
- mCurrentOperatingp = mCurrentp;
- mCurrentp = mCurrentp->mForward[0];
- return mCurrentOperatingp->mData;
- }
- else
- {
- //return NULL; // causes warning
- return (DATA_T)0; // equivalent, but no warning
- }
- }
- // same as getCurrentData() but a more intuitive name for the operation
- template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH>
- inline DATA_T LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::getNextData()
- {
- if (mCurrentp)
- {
- mCurrentOperatingp = mCurrentp;
- mCurrentp = mCurrentp->mForward[0];
- return mCurrentOperatingp->mData;
- }
- else
- {
- //return NULL; // causes compile warning
- return (DATA_T)0; // equivalent, but removes warning
- }
- }
- template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH>
- inline INDEX_T LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::getNextKey()
- {
- if (mCurrentp)
- {
- mCurrentOperatingp = mCurrentp;
- mCurrentp = mCurrentp->mForward[0];
- return mCurrentOperatingp->mIndex;
- }
- else
- {
- return mHead.mIndex;
- }
- }
- // return the key currently pointed to
- template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH>
- inline INDEX_T LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::getCurrentKeyWithoutIncrement()
- {
- if (mCurrentOperatingp)
- {
- return mCurrentOperatingp->mIndex;
- }
- else
- {
- //return NULL; // causes compile warning
- return (INDEX_T)0; // equivalent, but removes warning
- }
- }
- // remove the Node at mCurentOperatingp
- // leave mCurrentp and mCurentOperatingp on the next entry
- template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH>
- inline void LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::removeCurrentData()
- {
- if (mCurrentOperatingp)
- {
- removeData(mCurrentOperatingp->mIndex);
- }
- }
- template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH>
- inline void LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::deleteCurrentData()
- {
- if (mCurrentOperatingp)
- {
- deleteData(mCurrentOperatingp->mIndex);
- }
- }
- // reset the list and return the data currently pointed to, set mCurentOperatingp to that node and bump mCurrentp
- template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH>
- inline DATA_T LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::getFirstData()
- {
- mCurrentp = *(mHead.mForward);
- mCurrentOperatingp = *(mHead.mForward);
- if (mCurrentp)
- {
- mCurrentOperatingp = mCurrentp;
- mCurrentp = mCurrentp->mForward[0];
- return mCurrentOperatingp->mData;
- }
- else
- {
- //return NULL; // causes compile warning
- return (DATA_T)0; // equivalent, but removes warning
- }
- }
- template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH>
- inline INDEX_T LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::getFirstKey()
- {
- mCurrentp = *(mHead.mForward);
- mCurrentOperatingp = *(mHead.mForward);
- if (mCurrentp)
- {
- mCurrentOperatingp = mCurrentp;
- mCurrentp = mCurrentp->mForward[0];
- return mCurrentOperatingp->mIndex;
- }
- else
- {
- return mHead.mIndex;
- }
- }
- #endif