Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • examples/hashtable.cfa

    rab652e7 rd6d1f80  
     1// a type whose size is n
     2#define Z(n) char[n]
    13
    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)
     12forall( ztype(Zn), otype Te )
     13struct array {
     14  Te items[z(Zn)];
     15};
     16
     17// subscript operator for known-size array
     18forall( ztype(Zn), otype Te ) {
     19  Te & ?[?]( array(Zn, Te) &this, size_t idx ) with(this) {
     20    return items[idx];
     21  }
     22}
    323
    424#include <exception.hfa>
     
    626
    727
    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>
    1529
    1630trait has_hash( otype K ) {
     
    2741    struct hashtable {
    2842
     43        size_t item_count;
    2944        size_t n_buckets;
    30         dlist(tN, tE) *buckets;
    31        
    32         size_t item_count;
     45
    3346        float ff_next_warn_up;
    3447
    35         void (*defaultResumptionHandler) (ht_fill_limit_crossed &);
     48        dlist(tN, tE) buckets[ 0 ];
    3649    };
    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) ) {
    6050
    6151    float fill_frac( hashtable(K, tN, tE) & this ) with(this) {
    6252        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        }
    6364    }
    6465
     
    8283    void check_ff_warning( hashtable(K, tN, tE) & this ) with (this) {
    8384        if (fill_frac(this) > ff_next_warn_up) {
    84             throwResume (ht_fill_limit_crossed){};
     85            throwResume &(ht_fill_limit_crossed){};
    8586            ff_next_warn_up *= 2;
    8687        }
     
    107108}
    108109
    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 
    151110
    152111
     
    155114    unsigned int src_id;
    156115    unsigned int tgt_id;
     116
     117
    157118
    158119    DLISTED_MGD_EXPL_IN(request, ht_by_src)
     
    172133
    173134
    174 #include <stdlib.hfa>
     135
    175136
    176137int main() {
    177138
    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 );
    180146
    181147    request & wasnt_found = get(h_src, 17);
     
    205171    } catchResume(ht_fill_limit_crossed*) {
    206172        printf("fill limit tripped with h_src filled at %f\n", fill_frac(h_src));
    207         throwResume;
    208173    }
    209174
     
    212177    assert(! & get(h_src, 8000*25+1) );
    213178
    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);
    242180
    243181}
Note: See TracChangeset for help on using the changeset viewer.