-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathnnhash.cpp
221 lines (197 loc) · 4.65 KB
/
nnhash.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include "nnhash.h"
/* 汎用に使う、プロパティークラス */
NnHash properties;
/* Pair - ハッシュテーブルの要素 : キーと値のペアに関するクラス */
NnHash::Pair::~Pair()
{
delete value_;
}
inline void NnHash::Pair::replace( NnObject *val )
{
if( value_ != val )
delete value_;
value_ = val;
}
inline NnHash::Pair *NnHash::Pair::connect( NnHash::Pair *ele )
{
Pair *rv=next_;
next_ = ele;
return rv;
}
/* HashTable を初期化する
* return
* 0 ... 成功
* -1 ... 失敗
*/
int NnHash::init()
{
if( table == NULL ){
if( (table=new Pair*[size]) == NULL )
return -1;
for(int i=0;i<size;i++)
table[i] = NULL;
}
return 0;
}
/* NnHash::put
* key の値として rep を登録する。
* key == 0 の時、削除する。
* return
* 0 : 成功
* -1 : 初期化エラー(テーブル全体の確保の失敗)
* -2 : メモリ確保エラー(要素単位)
*/
int NnHash::put_(const NnString &key, NnObject *obj)
{
if( init() ) return -1;
int index=key.hashValue() % size;
if( table[index] == NULL ){
if( obj != NULL && (table[index]=new Pair(key,obj))==NULL )
return -2;
return 0;
}
Pair *cur=table[index];
Pair **pre=&table[index];
for(;;){
if( cur->key().compare(key)==0 ){
/* キーが同じ! */
if( obj != NULL ){
/* 値が非NULLの場合、要素を置換 */
cur->replace( obj );
}else{
/* 値が NULL の場合、要素の削除 */
*pre = cur->next();
delete cur;
}
return 0;
}
if( cur->next() == NULL ){
/* 新規オブジェクト */
if( obj != NULL ){
Pair *t=new Pair(key,obj);
if( t == NULL )
return -2;
cur->connect( t );
}
return 0;
}
pre = &cur->next_;
cur = cur->next();
}
}
NnObject *NnHash::get(const char *key)
{
if( table == NULL ) return NULL;
int index=NnString::hashValue(key) % size;
for(Pair *ptr=table[index] ; ptr != NULL ; ptr=ptr->next() ){
if( ptr->key().compare(key)==0 )
return ptr->value();
}
return NULL;
}
/* 連想配列を検索する。
* key キー値
* return
* 非NULL … オブジェクトへのポインタ
* NULL … マッチするオブジェクトは無かった。
*/
NnObject *NnHash::get(const NnString &key)
{
if( table == NULL ) return NULL;
int index=key.hashValue() % size;
for(Pair *ptr=table[index] ; ptr != NULL ; ptr=ptr->next() ){
if( ptr->key().compare(key)==0 )
return ptr->value();
}
return NULL;
}
/* デストラクタ
*/
NnHash::~NnHash()
{
if( table == NULL )
return;
for(int i=0;i<size;i++){
Pair *p=table[i];
while( p != NULL ){
Pair *nxt=p->next();
delete p;
p = nxt;
}
}
#ifdef ARRAY_DELETE_NEED_SIZE
delete[size]table;
#else
delete[]table;
#endif
}
/* ハッシュ用カーソル初期化
* hash - ハッシュ
*/
NnHash::Each::Each(const NnHash &h) : hash(h)
{
if( hash.table != NULL ){
index=-1;
nextindex();
}else{
index = 0;
ptr = NULL;
}
}
/* 内部配列に対するインデックスを一つ進める.
* 空のインデックスは読み飛ばす.
*/
void NnHash::Each::nextindex()
{
while( ++index < hash.size ){
if( hash.table[index] != NULL ){
ptr = hash.table[index];
return;
}
}
ptr = NULL;
index = 0;
}
/* ハッシュ用カーソルを一つ進める. */
void NnHash::Each::operator ++ ()
{
if( ptr == NULL )
return;
if( ptr->next() != NULL ){
ptr = ptr->next();
return;
}
nextindex();
}
NnObject *NnHash::Each::operator *()
{
return ptr;
}
NnHash::NnHash( const NnHash &o )
{
table = 0; size = o.size;
for( NnHash::Each p(o) ; p.more() ; ++p ){
this->put( p->key() , p->value()->clone() );
}
}
/* 環境変数の値を得る(環境変数の大文字/小文字を区別しない)
* var - 環境変数名
* none - 環境変数が存在しない時に返す値.
* return
* 環境変数の値
*/
const char *getEnv( const char *var , const char *none )
{
if( var == NULL || var[0] == '\0' )
return NULL;
const char *value=getenv(var);
if( value != NULL && value[0] != '\0' )
return value;
NnString var1(var);
var1.upcase();
return (value=getenv(var1.chars())) != NULL && value[0] != '\0'
? value : none ;
}