source: dev/trunk/ab5.0/jenga/include/common/Hashmap.h@ 520

Last change on this file since 520 was 520, checked in by dai_9181, 16 years ago

Hashmapクラスをjengaプロジェクトに移動。

File size: 4.2 KB
Line 
1#pragma once
2
3
4namespace Jenga{
5namespace Common{
6
7
8#define MAX_HASHMAP 65535
9template<class T> class Hashmap
10{
11 T* hashArray[MAX_HASHMAP];
12
13public:
14 virtual int GetHash( const char *keyName ) const
15 {
16 int key;
17 for(key=0;*keyName!='\0';keyName++){
18 key=((key<<8)+ *keyName )%MAX_HASHMAP;
19 }
20 return key;
21 }
22
23 Hashmap()
24 : isIteratorReady( false )
25 {
26 memset( hashArray, 0, MAX_HASHMAP*sizeof(T*) );
27 }
28 ~Hashmap()
29 {
30 Clear();
31 }
32 void Clear()
33 {
34 for( int i=0; i<MAX_HASHMAP; i++ )
35 {
36 T* temp = hashArray[i];
37 if( temp )
38 {
39 delete temp;
40 }
41 }
42 memset( hashArray, 0, MAX_HASHMAP*sizeof(T*) );
43 }
44
45 // 内容を破棄せずにすべて抜き取る
46 void PullOutAll()
47 {
48 memset( hashArray, 0, MAX_HASHMAP*sizeof(T*) );
49 }
50
51 bool Put( T* value )
52 {
53 int key = GetHash( value->GetKeyName().c_str() );
54
55 if(hashArray[key]){
56 T *temp = hashArray[key];
57 while( true ){
58 if( temp->IsDuplication( value ) )
59 {
60 // 重複している
61 return false;
62 }
63
64 if( temp->GetChainNext() == NULL )
65 {
66 break;
67 }
68 temp = temp->GetChainNext();
69 }
70 temp->SetChainNext( value );
71 }
72 else{
73 hashArray[key] = value;
74 }
75
76 return true;
77 }
78
79 T* GetHashArrayElement( const char *keyName )
80 {
81 return hashArray[GetHash(keyName)];
82 }
83 const T* GetHashArrayElement( const char *keyName ) const
84 {
85 return hashArray[GetHash(keyName)];
86 }
87
88 bool IsExist( const std::string &keyName ) const
89 {
90 int key = GetHash( keyName.c_str() );
91
92 if(hashArray[key]){
93 T *temp = hashArray[key];
94 while( true ){
95 if( temp->IsDuplication( keyName ) )
96 {
97 // 重複している
98 return true;
99 }
100
101 if( temp->GetChainNext() == NULL )
102 {
103 break;
104 }
105 temp = temp->GetChainNext();
106 }
107 }
108
109 return false;
110 }
111
112
113 /////////////////////////////////////////////////////////////////
114 // イテレータ
115 /////////////////////////////////////////////////////////////////
116private:
117 mutable std::vector<T*> iterator_Objects;
118 mutable int iterator_CurrentNext;
119 mutable bool isIteratorReady;
120public:
121 void Iterator_Init() const
122 {
123 iterator_Objects.clear();
124 iterator_CurrentNext = 0;
125
126 for( int i=0; i<MAX_HASHMAP; i++ ){
127 if( hashArray[i] ){
128 T* temp = hashArray[i];
129 while( temp )
130 {
131 iterator_Objects.push_back( temp );
132
133 temp = (T*)temp->GetChainNext();
134 }
135 }
136 }
137
138 isIteratorReady = true;
139 }
140 void Iterator_Reset() const
141 {
142 if( !isIteratorReady )
143 {
144 Jenga::Throw( "イテレータの準備ができていない" );
145 }
146 iterator_CurrentNext = 0;
147 }
148 bool Iterator_HasNext() const
149 {
150 return ( iterator_CurrentNext < (int)iterator_Objects.size() );
151 }
152 T *Iterator_GetNext() const
153 {
154 return iterator_Objects[iterator_CurrentNext++];
155 }
156 int Iterator_GetMaxCount() const
157 {
158 return (int)iterator_Objects.size();
159 }
160
161
162 // XMLシリアライズ用
163private:
164 friend class boost::serialization::access;
165 BOOST_SERIALIZATION_SPLIT_MEMBER();
166 template<class Archive> void load(Archive& ar, const unsigned int version)
167 {
168 std::vector<T *> objects;
169 ar & BOOST_SERIALIZATION_NVP( objects );
170
171 // 読み込み後の処理
172 Clear();
173 BOOST_FOREACH( T *object, objects )
174 {
175 Put( object );
176 }
177 Iterator_Init();
178 }
179 template<class Archive> void save(Archive& ar, const unsigned int version) const
180 {
181 // 保存準備
182 std::vector<T *> objects;
183 objects.clear();
184 Iterator_Reset();
185 while( Iterator_HasNext() )
186 {
187 objects.push_back( Iterator_GetNext() );
188 }
189
190 ar & BOOST_SERIALIZATION_NVP( objects );
191 }
192};
193
194template<class T> class ObjectInHashmap
195{
196 T *pNextObject;
197public:
198
199 ObjectInHashmap()
200 : pNextObject( NULL )
201 {
202 }
203 ~ObjectInHashmap()
204 {
205 if( pNextObject )
206 {
207 delete pNextObject;
208 }
209 }
210
211 virtual const std::string &GetKeyName() const = 0;
212 virtual bool IsDuplication( const T *value ) const
213 {
214 return ( GetKeyName() == value->GetName() );
215 }
216 virtual bool IsDuplication( const std::string &keyName ) const
217 {
218 return ( GetKeyName() == keyName );
219 }
220
221 T *GetChainNext()
222 {
223 return pNextObject;
224 }
225 const T *GetChainNext() const
226 {
227 return pNextObject;
228 }
229 void SetChainNext( T *pNextObject )
230 {
231 this->pNextObject = pNextObject;
232 }
233};
234
235
236}}
Note: See TracBrowser for help on using the repository browser.