Changes in / [b8e3941:6026628]


Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • examples/hashtable.cfa

    rb8e3941 r6026628  
     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 ) {
     
    2337};
    2438
    25 forall( otype K, dtype tN, dtype tE | $dlistable(tN, tE) | hkey(K, tN) | { void defaultResumptionHandler(ht_fill_limit_crossed &); } ) {
     39forall( otype K, dtype tN, dtype tE | $dlistable(tN, tE) | hkey(K, tN) ) {
    2640
    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 (*__stashed_defaultResumptionHandler) (ht_fill_limit_crossed &);
     48        dlist(tN, tE) buckets[ 0 ];
    3649    };
    37 
    38     void ?{}( hashtable(K, tN, tE) & this ) = void;
    39 //    void ?{}( hashtable(K, tN, tE) & this, size_t, dlist(tN, tE)* ) = void;
    40 
    41     void ?{}( hashtable(K, tN, tE) & this, size_t n_buckets, dlist(tN, tE) *buckets ) {
    42 
    43         this.n_buckets = n_buckets;
    44         this.buckets = buckets;
    45 
    46         this.item_count = 0;
    47         this.ff_next_warn_up = 0.5;
    48 
    49         this.__stashed_defaultResumptionHandler = defaultResumptionHandler;
    50 
    51         for ( i; n_buckets ) {
    52             ?{}( this.buckets[i] );
    53         }
    54     }
    55 }
    56 
    57 forall( otype K, dtype tN, dtype tE | $dlistable(tN, tE) | hkey(K, tN) ) {
    5850
    5951    float fill_frac( hashtable(K, tN, tE) & this ) with(this) {
    6052        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        }
    6164    }
    6265
     
    7982
    8083    void check_ff_warning( hashtable(K, tN, tE) & this ) with (this) {
    81         void (*defaultResumptionHandler) (ht_fill_limit_crossed &) = __stashed_defaultResumptionHandler;
    8284        if (fill_frac(this) > ff_next_warn_up) {
    83             throwResume (ht_fill_limit_crossed){};
     85            throwResume &(ht_fill_limit_crossed){};
    8486            ff_next_warn_up *= 2;
    8587        }
     
    106108}
    107109
    108 // tactical usage:
    109 // HASHTABLE_STATIC(int, item_by_prority, item, n, ht)
    110 //
    111 // intended equivalent:
    112 // hashtable_static(int, item_by_prority, item, Z(n)) ht;
    113 #define HASHTABLE_STATIC(K, tN, tE, n_buckets, obj) \
    114     struct __hashtable_static_ ## obj { \
    115         inline hashtable(K, tN, tE); \
    116         dlist(tN, tE) $items[n_buckets]; \
    117     }; \
    118     void ?{}( __hashtable_static_ ## obj & this )  { \
    119         ((hashtable(K, tN, tE) &)this){ n_buckets, this.$items }; \
    120     } \
    121     __hashtable_static_ ## obj obj;
    122 
    123 
    124 
    125 trait heaped(dtype T) {
    126     T * alloc( size_t );
    127     void free( void * );
    128 };
    129 
    130 void __dynamic_defaultResumptionHandler(ht_fill_limit_crossed & ex) {
    131     printf("dynamic limit crossed\n");
    132 }
    133 
    134 forall( otype K, dtype tN, dtype tE | $dlistable(tN, tE) | hkey(K, tN) | heaped( dlist(tN, tE) ) ) {
    135 
    136     struct hashtable_dynamic {
    137         inline hashtable(K, tN, tE);
    138     };
    139     void ?{}( hashtable_dynamic(K, tN, tE) & this, size_t n_buckets )  {
    140         void (*defaultResumptionHandler) (ht_fill_limit_crossed &) = __dynamic_defaultResumptionHandler;
    141         dlist(tN, tE) *buckets = alloc(n_buckets);
    142         ((hashtable(K, tN, tE) &)this){ n_buckets, buckets };
    143     }
    144     void ^?{}( hashtable_dynamic(K, tN, tE) & this ) {
    145         free(this.buckets);
    146     }
    147 }
    148 
    149 
    150110
    151111
     
    154114    unsigned int src_id;
    155115    unsigned int tgt_id;
     116
     117
    156118
    157119    DLISTED_MGD_EXPL_IN(request, ht_by_src)
     
    171133
    172134
    173 #include <stdlib.hfa>
     135
    174136
    175137int main() {
    176138
    177 
    178     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 );
    179146
    180147    request & wasnt_found = get(h_src, 17);
     
    204171    } catchResume(ht_fill_limit_crossed*) {
    205172        printf("fill limit tripped with h_src filled at %f\n", fill_frac(h_src));
    206         throwResume;
    207173    }
    208174
     
    211177    assert(! & get(h_src, 8000*25+1) );
    212178
    213 
    214 
    215     dlist(request_in_ht_by_src, request) * (*old_alloc)( size_t ) = alloc;
    216     dlist(request_in_ht_by_src, request) * alloc( size_t n ) {
    217         dlist(request_in_ht_by_src, request) * ret = old_alloc(n);
    218         printf("alloc'ed at %p\n", ret);
    219         return ret;
    220     }
    221 
    222     void (*old_free)( void * ) = free;
    223     void free( void * o ) {
    224         printf("free'ing at %p\n", o);
    225         old_free(o);
    226     }
    227 
    228     hashtable_dynamic(unsigned int, request_in_ht_by_src, request) ht2 = { 113 };
    229     request rs2[500];
    230     try {
    231         for (i; 500) {
    232             if (i % 10 == 0) {printf("%d(%f),", i, fill_frac(ht2));}
    233             rs2[i].src_id = 8000 * i;
    234             put(ht2, rs2[i]);
    235         }
    236     } catchResume(ht_fill_limit_crossed*) {
    237         printf("fill limit tripped with ht2 filled at %f\n", fill_frac(ht2));
    238         throwResume;
    239     }
    240 
     179    free(firstAlloc);
    241180
    242181}
Note: See TracChangeset for help on using the changeset viewer.