Changes in examples/hashtable.cfa [ab652e7:d6d1f80]
- File:
-
- 1 edited
-
examples/hashtable.cfa (modified) (9 diffs)
Legend:
- Unmodified
- Added
- Removed
-
examples/hashtable.cfa
rab652e7 rd6d1f80 1 // a type whose size is n 2 #define Z(n) char[n] 1 3 2 #include <containers/list.hfa> 4 // the inverse of Z(-) 5 #define z(Zn) sizeof(Zn) 6 7 // if you're expecting a Z(n), say so, by asking for a ztype, instead of dtype or otype 8 #define ztype(Zn) dtype Zn | sized(Zn) 9 10 // a "known-size" array 11 // an array of length n, whose elements are of Te, letting n be such that Zn is Z(n) 12 forall( ztype(Zn), otype Te ) 13 struct array { 14 Te items[z(Zn)]; 15 }; 16 17 // subscript operator for known-size array 18 forall( ztype(Zn), otype Te ) { 19 Te & ?[?]( array(Zn, Te) &this, size_t idx ) with(this) { 20 return items[idx]; 21 } 22 } 3 23 4 24 #include <exception.hfa> … … 6 26 7 27 8 9 void defaultResumptionHandler(ht_fill_limit_crossed &) { 10 printf("default resumption ht_fill_limit_crossed\n"); 11 } 12 13 void defaultTerminationHandler(ht_fill_limit_crossed &) = void; 14 28 #include <containers/list.hfa> 15 29 16 30 trait has_hash( otype K ) { … … 27 41 struct hashtable { 28 42 43 size_t item_count; 29 44 size_t n_buckets; 30 dlist(tN, tE) *buckets; 31 32 size_t item_count; 45 33 46 float ff_next_warn_up; 34 47 35 void (*defaultResumptionHandler) (ht_fill_limit_crossed &);48 dlist(tN, tE) buckets[ 0 ]; 36 49 }; 37 38 void ?{}( hashtable(K, tN, tE) & this ) = void;39 }40 41 forall( otype K, dtype tN, dtype tE | $dlistable(tN, tE) | hkey(K, tN) | { void defaultResumptionHandler(ht_fill_limit_crossed &); } ) {42 43 void ?{}( hashtable(K, tN, tE) & this, size_t n_buckets, dlist(tN, tE) *buckets ) {44 45 this.n_buckets = n_buckets;46 this.buckets = buckets;47 48 this.item_count = 0;49 this.ff_next_warn_up = 0.5;50 51 this.defaultResumptionHandler = defaultResumptionHandler;52 53 for ( i; n_buckets ) {54 ?{}( this.buckets[i] );55 }56 }57 }58 59 forall( otype K, dtype tN, dtype tE | $dlistable(tN, tE) | hkey(K, tN) ) {60 50 61 51 float fill_frac( hashtable(K, tN, tE) & this ) with(this) { 62 52 return ((float)item_count) / n_buckets; 53 } 54 55 void ?{}( hashtable(K, tN, tE) & this, int n_buckets ) { 56 57 this.item_count = 0; 58 this.n_buckets = n_buckets; 59 this.ff_next_warn_up = 0.5; 60 61 for ( int i = 0; i < n_buckets; i++ ) { 62 ?{}( this.buckets[i] ); 63 } 63 64 } 64 65 … … 82 83 void check_ff_warning( hashtable(K, tN, tE) & this ) with (this) { 83 84 if (fill_frac(this) > ff_next_warn_up) { 84 throwResume (ht_fill_limit_crossed){};85 throwResume &(ht_fill_limit_crossed){}; 85 86 ff_next_warn_up *= 2; 86 87 } … … 107 108 } 108 109 109 // tactical usage:110 // HASHTABLE_STATIC(int, item_by_prority, item, n, ht)111 //112 // intended equivalent:113 // hashtable_static(int, item_by_prority, item, Z(n)) ht;114 #define HASHTABLE_STATIC(K, tN, tE, n_buckets, obj) \115 struct __hashtable_static_ ## obj { \116 inline hashtable(K, tN, tE); \117 dlist(tN, tE) $items[n_buckets]; \118 }; \119 void ?{}( __hashtable_static_ ## obj & this ) { \120 ((hashtable(K, tN, tE) &)this){ n_buckets, this.$items }; \121 } \122 __hashtable_static_ ## obj obj;123 124 125 126 trait heaped(dtype T) {127 T * alloc( size_t );128 void free( void * );129 };130 131 void __dynamic_defaultResumptionHandler(ht_fill_limit_crossed & ex) {132 printf("dynamic limit crossed\n");133 }134 135 forall( otype K, dtype tN, dtype tE | $dlistable(tN, tE) | hkey(K, tN) | heaped( dlist(tN, tE) ) ) {136 137 struct hashtable_dynamic {138 inline hashtable(K, tN, tE);139 };140 void ?{}( hashtable_dynamic(K, tN, tE) & this, size_t n_buckets ) {141 void (*defaultResumptionHandler) (ht_fill_limit_crossed &) = __dynamic_defaultResumptionHandler;142 dlist(tN, tE) *buckets = alloc(n_buckets);143 ((hashtable(K, tN, tE) &)this){ n_buckets, buckets };144 }145 void ^?{}( hashtable_dynamic(K, tN, tE) & this ) {146 free(this.buckets);147 }148 }149 150 151 110 152 111 … … 155 114 unsigned int src_id; 156 115 unsigned int tgt_id; 116 117 157 118 158 119 DLISTED_MGD_EXPL_IN(request, ht_by_src) … … 172 133 173 134 174 #include <stdlib.hfa> 135 175 136 176 137 int main() { 177 138 178 179 HASHTABLE_STATIC(unsigned int, request_in_ht_by_src, request, 67, h_src) 139 void *firstAlloc = malloc( sizeof( hashtable(unsigned int, request_in_ht_by_src, request)) 140 + sizeof( dlist(request_in_ht_by_src, request) [67] ) 141 ); 142 hashtable(unsigned int, request_in_ht_by_src, request) & h_src = 143 * (hashtable(unsigned int, request_in_ht_by_src, request) *) firstAlloc; 144 145 ?{}( h_src, 67 ); 180 146 181 147 request & wasnt_found = get(h_src, 17); … … 205 171 } catchResume(ht_fill_limit_crossed*) { 206 172 printf("fill limit tripped with h_src filled at %f\n", fill_frac(h_src)); 207 throwResume;208 173 } 209 174 … … 212 177 assert(! & get(h_src, 8000*25+1) ); 213 178 214 215 216 dlist(request_in_ht_by_src, request) * (*old_alloc)( size_t ) = alloc; 217 dlist(request_in_ht_by_src, request) * alloc( size_t n ) { 218 dlist(request_in_ht_by_src, request) * ret = old_alloc(n); 219 printf("alloc'ed at %p\n", ret); 220 return ret; 221 } 222 223 void (*old_free)( void * ) = free; 224 void free( void * o ) { 225 printf("free'ing at %p\n", o); 226 old_free(o); 227 } 228 229 hashtable_dynamic(unsigned int, request_in_ht_by_src, request) ht2 = { 113 }; 230 request rs2[500]; 231 try { 232 for (i; 500) { 233 if (i % 10 == 0) {printf("%d(%f),", i, fill_frac(ht2));} 234 rs2[i].src_id = 8000 * i; 235 put(ht2, rs2[i]); 236 } 237 } catchResume(ht_fill_limit_crossed*) { 238 printf("fill limit tripped with ht2 filled at %f\n", fill_frac(ht2)); 239 throwResume; 240 } 241 179 free(firstAlloc); 242 180 243 181 }
Note:
See TracChangeset
for help on using the changeset viewer.