source: dev/trunk/ab5.0/abdev/BasicCompiler_Common/include/Hashmap.h@ 519

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

jenga.hを追加。

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