Ignore:
Timestamp:
Jun 24, 2020, 5:00:59 PM (4 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
c953163
Parents:
9791ab5 (diff), 7f9968a (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' into relaxed_ready

File:
1 edited

Legend:

Unmodified
Added
Removed
  • examples/hashtable.cfa

    r9791ab5 r8b58bae  
    1 // a type whose size is n
    2 #define Z(n) char[n]
    3 
    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 }
     1
     2#include <containers/list.hfa>
    233
    244#include <exception.hfa>
     
    266
    277
    28 #include <containers/list.hfa>
     8
     9void defaultResumptionHandler(ht_fill_limit_crossed &) {
     10    printf("default resumption ht_fill_limit_crossed\n");
     11}
     12
     13void defaultTerminationHandler(ht_fill_limit_crossed &) = void;
     14
    2915
    3016trait has_hash( otype K ) {
     
    4127    struct hashtable {
    4228
     29        size_t n_buckets;
     30        dlist(tN, tE) *buckets;
     31       
    4332        size_t item_count;
    44         size_t n_buckets;
    45 
    4633        float ff_next_warn_up;
    4734
    48         dlist(tN, tE) buckets[ 0 ];
     35        void (*defaultResumptionHandler) (ht_fill_limit_crossed &);
    4936    };
     37
     38    void ?{}( hashtable(K, tN, tE) & this ) = void;
     39}
     40
     41forall( 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
     59forall( otype K, dtype tN, dtype tE | $dlistable(tN, tE) | hkey(K, tN) ) {
    5060
    5161    float fill_frac( hashtable(K, tN, tE) & this ) with(this) {
    5262        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         }
    6463    }
    6564
     
    8382    void check_ff_warning( hashtable(K, tN, tE) & this ) with (this) {
    8483        if (fill_frac(this) > ff_next_warn_up) {
    85             throwResume &(ht_fill_limit_crossed){};
     84            throwResume (ht_fill_limit_crossed){};
    8685            ff_next_warn_up *= 2;
    8786        }
     
    108107}
    109108
     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
     126trait heaped(dtype T) {
     127    T * alloc( size_t );
     128    void free( void * );
     129};
     130
     131void __dynamic_defaultResumptionHandler(ht_fill_limit_crossed & ex) {
     132    printf("dynamic limit crossed\n");
     133}
     134
     135forall( 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
    110151
    111152
     
    114155    unsigned int src_id;
    115156    unsigned int tgt_id;
    116 
    117 
    118157
    119158    DLISTED_MGD_EXPL_IN(request, ht_by_src)
     
    133172
    134173
    135 
     174#include <stdlib.hfa>
    136175
    137176int main() {
    138177
    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 );
     178
     179    HASHTABLE_STATIC(unsigned int, request_in_ht_by_src, request, 67, h_src)
    146180
    147181    request & wasnt_found = get(h_src, 17);
     
    171205    } catchResume(ht_fill_limit_crossed*) {
    172206        printf("fill limit tripped with h_src filled at %f\n", fill_frac(h_src));
     207        throwResume;
    173208    }
    174209
     
    177212    assert(! & get(h_src, 8000*25+1) );
    178213
    179     free(firstAlloc);
    180 
    181 }
     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
     242
     243}
Note: See TracChangeset for help on using the changeset viewer.