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

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

静的リンクリンカの依存関係解決モジュールを製作中

File size: 5.1 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 IsExistDuplicationKeyName( const std::string &keyName ) const
89 {
90 int key = GetHash( keyName.c_str() );
91
92 if(hashArray[key]){
93 const 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 bool IsExist( const T* value ) const
113 {
114 int key = GetHash( value->GetKeyName().c_str() );
115
116 if(hashArray[key]){
117 const T *temp = hashArray[key];
118 while( true ){
119 if( temp->IsDuplication( value ) )
120 {
121 // 重複している
122 return true;
123 }
124
125 if( temp->GetChainNext() == NULL )
126 {
127 break;
128 }
129 temp = temp->GetChainNext();
130 }
131 }
132
133 return false;
134 }
135
136 const T *FindLike( const T* value ) const
137 {
138 int key = GetHash( value->GetKeyName().c_str() );
139
140 if(hashArray[key]){
141 const T *temp = hashArray[key];
142 while( true ){
143 if( temp->IsDuplication( value ) )
144 {
145 // 重複している
146 return temp;
147 }
148
149 if( temp->GetChainNext() == NULL )
150 {
151 break;
152 }
153 temp = temp->GetChainNext();
154 }
155 }
156
157 return NULL;
158 }
159
160
161 /////////////////////////////////////////////////////////////////
162 // イテレータ
163 /////////////////////////////////////////////////////////////////
164private:
165 mutable std::vector<T*> iterator_Objects;
166 mutable int iterator_CurrentNext;
167 mutable bool isIteratorReady;
168public:
169 void Iterator_Init() const
170 {
171 iterator_Objects.clear();
172 iterator_CurrentNext = 0;
173
174 for( int i=0; i<MAX_HASHMAP; i++ ){
175 if( hashArray[i] ){
176 T* temp = hashArray[i];
177 while( temp )
178 {
179 iterator_Objects.push_back( temp );
180
181 temp = (T*)temp->GetChainNext();
182 }
183 }
184 }
185
186 isIteratorReady = true;
187 }
188 void Iterator_Reset() const
189 {
190 if( !isIteratorReady )
191 {
192 Jenga::Throw( "イテレータの準備ができていない" );
193 }
194 iterator_CurrentNext = 0;
195 }
196 bool Iterator_HasNext() const
197 {
198 return ( iterator_CurrentNext < (int)iterator_Objects.size() );
199 }
200 T *Iterator_GetNext() const
201 {
202 return iterator_Objects[iterator_CurrentNext++];
203 }
204 int Iterator_GetMaxCount() const
205 {
206 return (int)iterator_Objects.size();
207 }
208
209
210 // XMLシリアライズ用
211private:
212 friend class boost::serialization::access;
213 BOOST_SERIALIZATION_SPLIT_MEMBER();
214 template<class Archive> void load(Archive& ar, const unsigned int version)
215 {
216 std::vector<T *> objects;
217 ar & BOOST_SERIALIZATION_NVP( objects );
218
219 // 読み込み後の処理
220 Clear();
221 BOOST_FOREACH( T *object, objects )
222 {
223 Put( object );
224 }
225 Iterator_Init();
226 }
227 template<class Archive> void save(Archive& ar, const unsigned int version) const
228 {
229 // 保存準備
230 std::vector<T *> objects;
231 objects.clear();
232 Iterator_Reset();
233 while( Iterator_HasNext() )
234 {
235 objects.push_back( Iterator_GetNext() );
236 }
237
238 ar & BOOST_SERIALIZATION_NVP( objects );
239 }
240};
241
242template<class T> class ObjectInHashmap
243{
244 T *pNextObject;
245public:
246
247 ObjectInHashmap()
248 : pNextObject( NULL )
249 {
250 }
251 ~ObjectInHashmap()
252 {
253 if( pNextObject )
254 {
255 delete pNextObject;
256 }
257 }
258
259 virtual const std::string &GetKeyName() const = 0;
260 virtual bool IsDuplication( const T *value ) const
261 {
262 return ( GetKeyName() == value->GetName() );
263 }
264 virtual bool IsDuplication( const std::string &keyName ) const
265 {
266 return ( GetKeyName() == keyName );
267 }
268
269 T *GetChainNext()
270 {
271 return pNextObject;
272 }
273 const T *GetChainNext() const
274 {
275 return pNextObject;
276 }
277 void SetChainNext( T *pNextObject )
278 {
279 this->pNextObject = pNextObject;
280 }
281};
282
283
284}}
Note: See TracBrowser for help on using the repository browser.