source: dev/trunk/abdev/BasicCompiler_Common/include/Hashmap.h@ 377

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