123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565 |
- /* -*- Mode: C++; tab-width: 3; indent-tabs-mode: t; c-basic-offset: 3 -*- */
- /*================================================================
- *
- * Project : Freyja
- * Author : Mongoose
- * Website : http://www.westga.edu/~stu7440/
- * Email : stu7440@westga.edu
- * Object : Map
- * License : No use w/o permission (C) 2000-2002 Mongoose
- * Comments: mtk Template list
- *
- * This file was generated using Mongoose's C++
- * template generator script. <stu7440@westga.edu>
- *
- *-- History ------------------------------------------------
- *
- * 2002.02.19:
- * Mongoose - Using RBTree and list overlay for faster access
- *
- * Access: O(1)/O(n)/O(logn) ?
- * Insert: O(nlogn) ?
- * Remove: O(nlogn) ?
- *
- * 2002.02.16:
- * Mongoose - Binary tree overlay started... at 0300 /_\ Zzzz
- *
- * 2002.02.01:
- * Mongoose - Dug out of cobwebs and fixed up
- * Yes, I believe in code reuse! =)
- *
- * 2000.10.26:
- * Mongoose - Created
- ================================================================*/
-
-
- #ifndef _MAP_H_
- #define _MAP_H_
-
- #include <stdlib.h>
- #include <stdio.h>
-
- #include <Tree.h>
-
- #ifdef DEBUG_MEMORY
- #include <memory_test.h>
- #endif
-
-
-
- template <class K, class D> class MapNode
- {
- public:
-
- MapNode(K key, D data)
- {
- _data = data;
- _key = key;
- _next = NULL;
- }
-
-
- ~MapNode()
- {
- }
-
-
- void Key(K key)
- {
- _key = key;
- }
-
-
- K Key()
- {
- return _key;
- }
-
-
- void Data(D data)
- {
- _data = data;
- }
-
-
- D Data()
- {
- return _data;
- }
-
-
- MapNode<K, D> *Next()
- {
- return _next;
- }
-
-
- void Next(MapNode<K, D> *next)
- {
- _next = next;
- }
-
- private:
-
- MapNode<K, D> *_next;
-
- K _key;
-
- D _data;
- };
-
-
- template <class K, class D> class Map
- {
- public:
-
- Map()
- {
- UnSetError();
- _num_items = 0;
- _head = NULL;
- _current = NULL;
- _cache = NULL;
- }
-
-
- ~Map()
- {
- Clear();
- }
-
-
- void Clear()
- {
- UnSetError();
- _num_items = 0;
- _cache = NULL;
-
- while (_head)
- {
- _current = _head;
- _head = _head->Next();
- delete _current;
- }
-
- _tree.Clear();
- }
-
-
- void SetError()
- {
- _error = true;
- }
-
-
- void UnSetError()
- {
- _error = false;
- }
-
-
- bool GetError()
- {
- return _error;
- }
-
-
- D FindDataByKey(K key)
- {
- MapNode<K, D> *current = NULL;
- MapNode<K, D> *next = NULL;
-
-
- if (_head)
- {
- UnSetError();
-
- if (_cache)
- {
- next = _cache->Next();
- }
-
- // Mongoose 2002.02.19, Optimize for sequential searches
- if (next && key == next->Key())
- {
- current = next;
- }
- else // Mongoose 2002.02.19, Use search algorithm otherwise
- {
- current = _tree.SearchByKey(key, &_error);
-
- if (_error)
- return false;
- }
-
- if (current)
- {
- _cache = _current = current;
- return current->Data();
- }
- }
-
- SetError();
- return 0;
- }
-
-
- D operator [] (K key)
- {
- return FindDataByKey(key);
- }
-
-
- K FindKeyByData(D data)
- {
- MapNode<K, D> *current = _head;
- MapNode<K, D> *last = NULL;
-
-
- UnSetError();
-
- while (current)
- {
- // Found
- if (current->Data() == data)
- {
- _cache = current;
- return current->Key();
- }
-
- last = current;
- current = current->Next();
- }
-
- SetError();
-
- return 0;
- }
-
-
- D getCache()
- {
- if (_cache == 0x0)
- {
- printf("Map::getCache> Bad request - should segfault\n");
- }
-
- return _cache->Data();
- }
-
-
- bool findKey(K key)
- {
- MapNode<K, D> *current = NULL;
- MapNode<K, D> *next = NULL;
-
- if (_head)
- {
- UnSetError();
-
- if (_cache)
- {
- if (_cache->Key() == key)
- {
- return true;
- }
-
- next = _cache->Next();
- }
-
- // Mongoose 2002.02.19, Optimize for sequential searches
- if (next && key == next->Key())
- {
- current = next;
- }
- else // Mongoose 2002.02.19, Use search algorithm otherwise
- {
- current = _tree.SearchByKey(key, &_error);
- }
-
- if (current)
- {
- _cache = _current = current;
- //curData = current->Data();
- return true;
- }
- }
-
- SetError();
- return false;
- }
-
-
- bool Add(K key, D data)
- {
- MapNode<K, D> *node;
-
-
- UnSetError();
- node = new MapNode<K, D>(key, data);
- _num_items++;
- return Add(node);
- }
-
-
- bool Add(MapNode<K, D> *node)
- {
- MapNode<K, D> *current = _head;
- MapNode<K, D> *last = NULL;
-
-
- if (!node)
- return false;
-
- UnSetError();
-
- if (_head)
- {
- current = _head;
- last = NULL;
-
- while (current)
- {
- // Prepend
- if (current->Key() > node->Key())
- {
- node->Next(current);
-
- if (current == _head)
- {
- _head = node;
- }
- else if (last)
- {
- last->Next(node);
- }
-
- _tree.Insert(node->Key(), node);
- return true;
- }
-
- last = current;
- current = current->Next();
- }
-
- // Append
- last->Next(node);
- }
- else
- {
- _head = node;
- }
-
- _tree.Insert(node->Key(), node);
- return true;
- }
-
-
- void RemoveByKey(K key)
- {
- MapNode<K, D> *current = _head;
- MapNode<K, D> *last = NULL;
-
-
- UnSetError();
-
- _cache = NULL;
-
- while (current)
- {
- // Remove
- if (current->Key() == key)
- {
- if (current == _head)
- {
- _head = current->Next();
- }
- else
- {
- last->Next(current->Next());
- }
-
- if (_current == current)
- {
- _current = NULL;
- }
-
- _tree.RemoveByKey(current->Key());
- delete current;
- _num_items--;
-
- return;
- }
-
- last = current;
- current = current->Next();
- }
-
- SetError();
- }
-
-
- void RemoveByData(D data)
- {
- MapNode<K, D> *current = _head;
- MapNode<K, D> *last = NULL;
-
-
- UnSetError();
-
- _cache = NULL;
-
- while (current)
- {
- // Remove
- if (current->Data() == data)
- {
- if (current == _head)
- {
- _head = current->Next();
- }
- else
- {
- last->Next(current->Next());
- }
-
- if (_current == current)
- {
- _current = NULL;
- }
-
- _tree.RemoveByKey(current->Key());
- delete current;
- _num_items--;
-
- return;
- }
-
- last = current;
- current = current->Next();
- }
-
- SetError();
- }
-
-
- bool Empty()
- {
- return (_head == NULL);
- }
-
-
- unsigned int count()
- {
- return _num_items;
- }
-
- unsigned int NumItems()
- {
- return _num_items;
- }
-
-
- void Print(void (*print_key_func)(K), void (*print_data_func)(D))
- {
- MapNode<K, D> *current = _head;
-
-
- UnSetError();
-
- if (!print_key_func || !print_data_func)
- {
- SetError();
- return;
- }
-
- printf(" [%i] {\n", _num_items);
-
- while (current)
- {
- printf("(");
- (*print_key_func)(current->Key());
- printf(", ");
- (*print_data_func)(current->Data());
- printf("), ");
-
- current = current->Next();
- fflush(stdout);
- }
-
- printf(" }\n");
- }
-
-
- void Reset()
- {
- _current = _head;
- _cache = _head;
- }
-
-
- bool operator ++ (int dummy)
- {
- return Next();
- }
-
-
- bool Next()
- {
- if (_current)
- {
- _current = _current->Next();
- }
-
- return (_current != NULL);
- }
-
-
- bool CurrentExists()
- {
- return (_current != 0);
- }
-
-
- K CurrentKey()
- {
- UnSetError();
-
- if (!_current)
- {
- SetError();
- return 0;
- }
-
- return _current->Key();
- }
-
-
- D Current()
- {
- UnSetError();
-
- if (!_current)
- {
- SetError();
- return 0;
- }
-
- return _current->Data();
- }
-
- private:
-
- unsigned int _num_items;
-
- bool _error;
-
- Tree<K, MapNode<K, D> *> _tree;
-
- MapNode<K, D> *_head;
-
- MapNode<K, D> *_current;
-
- MapNode<K, D> *_cache;
- };
- #endif
|