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

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

IsExistIsExistDuplicationKeyName
・キー名ではなく、インスタンスそのものの重複を発見するためのIsExistメソッドを実装。

File size: 4.7 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
137 /////////////////////////////////////////////////////////////////
138 // イテレータ
139 /////////////////////////////////////////////////////////////////
140private:
141 mutable std::vector<T*> iterator_Objects;
142 mutable int iterator_CurrentNext;
143 mutable bool isIteratorReady;
144public:
145 void Iterator_Init() const
146 {
147 iterator_Objects.clear();
148 iterator_CurrentNext = 0;
149
150 for( int i=0; i<MAX_HASHMAP; i++ ){
151 if( hashArray[i] ){
152 T* temp = hashArray[i];
153 while( temp )
154 {
155 iterator_Objects.push_back( temp );
156
157 temp = (T*)temp->GetChainNext();
158 }
159 }
160 }
161
162 isIteratorReady = true;
163 }
164 void Iterator_Reset() const
165 {
166 if( !isIteratorReady )
167 {
168 Jenga::Throw( "イテレータの準備ができていない" );
169 }
170 iterator_CurrentNext = 0;
171 }
172 bool Iterator_HasNext() const
173 {
174 return ( iterator_CurrentNext < (int)iterator_Objects.size() );
175 }
176 T *Iterator_GetNext() const
177 {
178 return iterator_Objects[iterator_CurrentNext++];
179 }
180 int Iterator_GetMaxCount() const
181 {
182 return (int)iterator_Objects.size();
183 }
184
185
186 // XMLシリアライズ用
187private:
188 friend class boost::serialization::access;
189 BOOST_SERIALIZATION_SPLIT_MEMBER();
190 template<class Archive> void load(Archive& ar, const unsigned int version)
191 {
192 std::vector<T *> objects;
193 ar & BOOST_SERIALIZATION_NVP( objects );
194
195 // 読み込み後の処理
196 Clear();
197 BOOST_FOREACH( T *object, objects )
198 {
199 Put( object );
200 }
201 Iterator_Init();
202 }
203 template<class Archive> void save(Archive& ar, const unsigned int version) const
204 {
205 // 保存準備
206 std::vector<T *> objects;
207 objects.clear();
208 Iterator_Reset();
209 while( Iterator_HasNext() )
210 {
211 objects.push_back( Iterator_GetNext() );
212 }
213
214 ar & BOOST_SERIALIZATION_NVP( objects );
215 }
216};
217
218template<class T> class ObjectInHashmap
219{
220 T *pNextObject;
221public:
222
223 ObjectInHashmap()
224 : pNextObject( NULL )
225 {
226 }
227 ~ObjectInHashmap()
228 {
229 if( pNextObject )
230 {
231 delete pNextObject;
232 }
233 }
234
235 virtual const std::string &GetKeyName() const = 0;
236 virtual bool IsDuplication( const T *value ) const
237 {
238 return ( GetKeyName() == value->GetName() );
239 }
240 virtual bool IsDuplication( const std::string &keyName ) const
241 {
242 return ( GetKeyName() == keyName );
243 }
244
245 T *GetChainNext()
246 {
247 return pNextObject;
248 }
249 const T *GetChainNext() const
250 {
251 return pNextObject;
252 }
253 void SetChainNext( T *pNextObject )
254 {
255 this->pNextObject = pNextObject;
256 }
257};
258
259
260}}
Note: See TracBrowser for help on using the repository browser.