@@ -4,6 +4,7 @@ import std::map::hashmap;
4
4
import std:: uint;
5
5
import std:: int;
6
6
import std:: vec;
7
+ import std:: option;
7
8
import std:: option:: none;
8
9
import std:: option:: some;
9
10
import front:: ast;
@@ -104,6 +105,108 @@ fn new_uint_hash[V]() -> std::map::hashmap[uint, V] {
104
105
ret std:: map:: mk_hashmap[ uint, V ] ( hasher, eqer) ;
105
106
}
106
107
108
+ fn new_seq_hash[ K , V ] ( fn ( & K ) -> uint key_idx,
109
+ fn ( & uint) -> K idx_key) -> std:: map:: hashmap[ K , V ] {
110
+ fn ensure_size[ V ] ( & mutable vec[ mutable option:: t[ V ] ] bkts, uint idx) {
111
+ auto bkt_len = vec:: len ( bkts) ;
112
+ if ( idx >= bkt_len) {
113
+ auto needed = idx - bkt_len + 1 u;
114
+ auto new = vec:: init_elt_mut ( option:: none[ V ] , needed) ;
115
+ bkts += new;
116
+ }
117
+ }
118
+
119
+ obj seq_hash[ K , V ] ( mutable uint nelts,
120
+ mutable vec[ mutable option:: t[ V ] ] bkts,
121
+ fn ( & K ) -> uint key_idx,
122
+ fn ( & uint) -> K idx_key) {
123
+
124
+ fn size ( ) -> uint { nelts }
125
+
126
+ fn insert ( & K key , & V value ) -> bool {
127
+ auto idx = key_idx ( key) ;
128
+ ensure_size ( bkts, idx) ;
129
+ if ( option:: is_some ( bkts. ( idx) ) ) {
130
+ bkts. ( idx) = option:: some ( value) ;
131
+ ret false;
132
+ } else {
133
+ bkts. ( idx) = option:: some ( value) ;
134
+ nelts += 1 u;
135
+ ret true;
136
+ }
137
+ }
138
+
139
+ fn contains_key ( & K key ) -> bool {
140
+ auto idx = key_idx ( key) ;
141
+ ensure_size ( bkts, idx) ;
142
+ if ( option:: is_some ( bkts. ( idx) ) ) {
143
+ ret true ;
144
+ } else {
145
+ ret false ;
146
+ }
147
+ }
148
+
149
+ fn get ( & K key ) -> V {
150
+ ret alt ( self . find ( key) ) {
151
+ case ( option:: some ( ?v) ) { v }
152
+ case ( _) { fail }
153
+ } ;
154
+ }
155
+
156
+ fn find ( & K key ) -> option:: t [ V ] {
157
+ auto idx = key_idx ( key) ;
158
+ ensure_size ( bkts, idx) ;
159
+ ret bkts. ( idx) ;
160
+ }
161
+
162
+ fn remove ( & K key ) -> option:: t [ V ] {
163
+ auto idx = key_idx ( key) ;
164
+ ensure_size ( bkts, idx) ;
165
+ auto val = bkts. ( idx) ;
166
+ if ( option:: is_some ( val) ) {
167
+ bkts. ( idx) = option:: none;
168
+ nelts -= 1 u;
169
+ }
170
+ ret val;
171
+ }
172
+
173
+ fn rehash ( ) { }
174
+
175
+ iter items( ) -> @tup ( K , V ) {
176
+ auto idx = 0 u;
177
+ auto bktsize = vec:: len ( bkts) ;
178
+ while ( idx < bktsize) {
179
+ alt ( bkts. ( idx) ) {
180
+ case ( option:: some ( ?v) ) {
181
+ // FIXME: Appease alias analysis
182
+ auto value = v;
183
+ put @tup( idx_key ( idx) , value) ;
184
+ }
185
+ case ( _) { }
186
+ }
187
+ idx += 1 u;
188
+ }
189
+ }
190
+ }
191
+
192
+ let vec[ mutable option:: t[ V ] ] bkts = [ mutable] ;
193
+ ret seq_hash[ K , V ] ( 0 u, bkts, key_idx, idx_key) ;
194
+ }
195
+
196
+ // A specialized map for keys that are sequential ints
197
+ fn new_seq_int_hash[ V ] ( ) -> std:: map:: hashmap[ int, V ] {
198
+ auto key_idx = fn ( & int key) -> uint { key as uint } ;
199
+ auto idx_key = fn ( & uint idx) -> int { idx as int } ;
200
+ ret new_seq_hash ( key_idx, idx_key) ;
201
+ }
202
+
203
+ // A specialized map for keys that are sequential uints
204
+ fn new_seq_uint_hash[ V ] ( ) -> std:: map:: hashmap[ uint, V ] {
205
+ auto key_idx = fn ( & uint key) -> uint { key } ;
206
+ auto idx_key = fn ( & uint idx) -> uint { idx } ;
207
+ ret new_seq_hash ( key_idx, idx_key) ;
208
+ }
209
+
107
210
fn istr ( int i) -> str { ret int:: to_str ( i, 10 u) ; }
108
211
109
212
fn uistr ( uint i) -> str { ret uint:: to_str ( i, 10 u) ; }
0 commit comments