cvsuser     03/11/11 07:17:20

  Modified:    include/parrot hash.h misc.h
               src      hash.c utils.c
  Log:
  some rand48 functions; randomize hash sorting
  
  Revision  Changes    Path
  1.19      +8 -6      parrot/include/parrot/hash.h
  
  Index: hash.h
  ===================================================================
  RCS file: /cvs/public/parrot/include/parrot/hash.h,v
  retrieving revision 1.18
  retrieving revision 1.19
  diff -u -w -r1.18 -r1.19
  --- hash.h    7 Nov 2003 16:17:33 -0000       1.18
  +++ hash.h    11 Nov 2003 15:17:16 -0000      1.19
  @@ -1,7 +1,7 @@
   /* hash.h
    *  Copyright: 2001-2003 The Perl Foundation.  All Rights Reserved.
    *  CVS Info
  - *     $Id: hash.h,v 1.18 2003/11/07 16:17:33 boemmels Exp $
  + *     $Id: hash.h,v 1.19 2003/11/11 15:17:16 leo Exp $
    *  Overview:
    *     Hashtable implementation
    *  Data Structure and Algorithms:
  @@ -48,7 +48,7 @@
   
   typedef int    (*hash_comp_fn)(Parrot_Interp, void*, void*);
   typedef void   (*hash_mark_key_fn)(Parrot_Interp, PObj *);
  -typedef size_t (*hash_hash_key_fn)(Parrot_Interp, void*);
  +typedef size_t (*hash_hash_key_fn)(Parrot_Interp, struct _hash*, void*);
   
   struct _hash {
       Buffer buffer;              /* This struct is a Buffer subclass! */
  @@ -59,13 +59,15 @@
       PARROT_DATA_TYPES entry_type;   /* type of value */
       size_t value_size;          /* currently unused, if set this size
                                      at value is copied as a hash_entry */
  -    hash_comp_fn   compare;
  -    hash_hash_key_fn hash_val;
  -    hash_mark_key_fn mark_key;
  +    size_t seed;                /* randomizes the hash_key generation
  +                                   updated for each new hash */
  +    hash_comp_fn   compare;     /* compare two keys, 0 = equal */
  +    hash_hash_key_fn hash_val;  /* generate a hash value for key */
  +    hash_mark_key_fn mark_key;  /* mark a key being alive */
   };
   
   Hash * new_hash(Interp * interpreter);
  -Hash * new_hash_x(Interp * interpreter,
  +Hash * new_hash_x(Interp *, PARROT_DATA_TYPES, size_t val_size,
           hash_comp_fn, hash_hash_key_fn, hash_mark_key_fn);
   Hash * new_cstring_hash(Interp *interpreter);
   Hash * hash_clone(Interp * interpreter, Hash * src);
  
  
  
  1.14      +7 -1      parrot/include/parrot/misc.h
  
  Index: misc.h
  ===================================================================
  RCS file: /cvs/public/parrot/include/parrot/misc.h,v
  retrieving revision 1.13
  retrieving revision 1.14
  diff -u -w -r1.13 -r1.14
  --- misc.h    9 Sep 2003 10:25:41 -0000       1.13
  +++ misc.h    11 Nov 2003 15:17:16 -0000      1.14
  @@ -1,7 +1,7 @@
   /* misc.h
    *  Copyright: 2001-2003 The Perl Foundation.  All Rights Reserved.
    *  CVS Info
  - *     $Id: misc.h,v 1.13 2003/09/09 10:25:41 leo Exp $
  + *     $Id: misc.h,v 1.14 2003/11/11 15:17:16 leo Exp $
    *  Overview:
    *     Miscellaneous functions, mainly the Parrot_sprintf family
    *  Data Structure and Algorithms:
  @@ -29,6 +29,12 @@
   
   INTVAL   intval_mod(INTVAL i2, INTVAL i3);
   FLOATVAL floatval_mod(FLOATVAL n2, FLOATVAL n3);
  +
  +FLOATVAL Parrot_float_rand(INTVAL how_random);
  +INTVAL Parrot_uint_rand(INTVAL how_random);
  +INTVAL Parrot_int_rand(INTVAL how_random);
  +INTVAL Parrot_range_rand(INTVAL from, INTVAL to, INTVAL how_random);
  +void Parrot_srand(INTVAL seed);
   
   /*
    * misc.c
  
  
  
  1.52      +31 -25    parrot/src/hash.c
  
  Index: hash.c
  ===================================================================
  RCS file: /cvs/public/parrot/src/hash.c,v
  retrieving revision 1.51
  retrieving revision 1.52
  diff -u -w -r1.51 -r1.52
  --- hash.c    7 Nov 2003 16:17:35 -0000       1.51
  +++ hash.c    11 Nov 2003 15:17:20 -0000      1.52
  @@ -1,7 +1,7 @@
   /* hash.c
    *  Copyright: 2001-2003 The Perl Foundation.  All Rights Reserved.
    *  CVS Info
  - *     $Id: hash.c,v 1.51 2003/11/07 16:17:35 boemmels Exp $
  + *     $Id: hash.c,v 1.52 2003/11/11 15:17:20 leo Exp $
    *  Overview:
    *  Data Structure and Algorithms:
    *     A hashtable contains an array of bucket indexes. Buckets
  @@ -22,12 +22,14 @@
    *                    hash keys are now (void *)
    *                    add new_cstring_hash() function
    *
  - *     2003.11.04 leo bucket->value is now a plain pointer, no nore
  + *     2003.11.04 leo bucket->value is now a plain pointer, no more
    *                    an HASH_ENTRY
    *                    With little changes, we can again store
    *                    arbitrary items if needed, s. TODO in code
    *     2003.11.06 boemmels renamed HASH and HASHBUCKET
    *                     to Hash and HashBucket
  + *     2003.11.11 leo randomize key_hash seed
  + *                    extend new_hash_x() init call by value_type and _size.
    *
    *  Notes:
    *     Future optimizations:
  @@ -82,21 +84,20 @@
   =cut */
   
   static size_t
  -key_hash_STRING(Interp *interpreter, void *value)
  +key_hash_STRING(Interp *interpreter, Hash *hash, void *value)
   {
       char *buffptr = ((STRING* )value)->strstart;
  -    INTVAL len = ((STRING* )value)->bufused;
  -    /* TODO randomize this for each new_hash */
  -    register size_t hash = 5381;
  +    UINTVAL len = ((STRING* )value)->bufused;
  +    register size_t h = hash->seed;
   
       UNUSED(interpreter);
   
       while (len--) {
  -        hash += hash << 5;
  -        hash += *buffptr++;
  +        h += h << 5;
  +        h += *buffptr++;
       }
   
  -    return hash;
  +    return h;
   }
   
   static int
  @@ -106,16 +107,15 @@
   }
   
   static size_t
  -key_hash_cstring(Interp *interpreter, void *value)
  +key_hash_cstring(Interp *interpreter, Hash* hash, void *value)
   {
  -    /* TODO randomize this for each new_hash */
  -    register size_t hash = 5381;
  +    register size_t h = hash->seed;
       unsigned char * p = (unsigned char *) value;
       while (*p) {
  -        hash += hash << 5;
  -        hash += *p++;
  +        h += h << 5;
  +        h += *p++;
       }
  -    return hash;
  +    return h;
   }
   
   static int
  @@ -254,7 +254,8 @@
               BucketIndex bucketIdx = *bucketIdxP;
               bucket = getBucket(hash, bucketIdx);
               new_loc =
  -                (hash->hash_val)(interpreter, bucket->key) & new_max_chain;
  +                (hash->hash_val)(interpreter, hash, bucket->key) &
  +                    new_max_chain;
               if (new_loc != hi) {
                   /* Remove from table */
                   *bucketIdxP = bucket->next;
  @@ -329,6 +330,8 @@
   new_hash(Interp *interpreter)
   {
       return new_hash_x(interpreter,
  +            enum_type_PMC,
  +            0,
               STRING_compare,     /* STRING compare */
               key_hash_STRING,    /*        hash */
               pobject_lives);     /*        mark */
  @@ -338,13 +341,15 @@
   new_cstring_hash(Interp *interpreter)
   {
       return new_hash_x(interpreter,
  +            enum_type_PMC,
  +            0,
               cstring_compare,     /* cstring compare */
               key_hash_cstring,    /*        hash */
               (hash_mark_key_fn)0);/* no     mark */
   }
   
   Hash *
  -new_hash_x(Interp *interpreter,
  +new_hash_x(Interp *interpreter, PARROT_DATA_TYPES val_type, size_t val_size,
           hash_comp_fn compare, hash_hash_key_fn keyhash,
           hash_mark_key_fn mark)
   {
  @@ -352,9 +357,9 @@
       hash->compare = compare;
       hash->hash_val = keyhash;
       hash->mark_key = mark;
  -    /* TODO make next 2 params configurable */
  -    hash->entry_type = enum_type_PMC;
  -    hash->value_size = 0;       /* extra size */
  +    hash->entry_type = val_type;
  +    hash->value_size = val_size;       /* extra size */
  +    hash->seed = (size_t) Parrot_uint_rand(0);
   
       /*      PObj_report_SET(&hash->buffer); */
   
  @@ -433,7 +438,7 @@
   HashBucket *
   hash_get_bucket(Interp *interpreter, Hash *hash, void *key)
   {
  -    UINTVAL hashval = (hash->hash_val)(interpreter, key);
  +    UINTVAL hashval = (hash->hash_val)(interpreter, hash, key);
       HashIndex *table = (HashIndex *)hash->buffer.bufstart;
       BucketIndex chain = table[hashval & hash->max_chain];
       return find_bucket(interpreter, hash, chain, key);
  @@ -465,7 +470,7 @@
   
       /*      dump_hash(interpreter, hash); */
   
  -    hashval = (hash->hash_val)(interpreter, key);
  +    hashval = (hash->hash_val)(interpreter, hash, key);
       table = (BucketIndex *)hash->buffer.bufstart;
       assert(table);
       chain = table[hashval & hash->max_chain];
  @@ -498,7 +503,7 @@
       HashBucket *bucket;
       HashBucket *prev = NULL;
   
  -    hashval = (hash->hash_val)(interpreter, key);
  +    hashval = (hash->hash_val)(interpreter, hash, key);
       slot = hashval & hash->max_chain;
   
       /*
  @@ -535,7 +540,8 @@
       HashIndex i;
       Hash *dest;
   
  -    dest = new_hash_x(interp, hash->compare, hash->hash_val, hash->mark_key);
  +    dest = new_hash_x(interp, hash->entry_type, hash->value_size,
  +            hash->compare, hash->hash_val, hash->mark_key);
       for (i = 0; i <= hash->max_chain; i++) {
           BucketIndex bi = lookupBucketIndex(hash, i);
           while (bi != NULLBucketIndex) {
  @@ -545,7 +551,7 @@
               switch (hash->entry_type) {
               case enum_hash_undef:
               case enum_hash_int:
  -            case enum_hash_num:
  +            case enum_hash_num: /* TODO use value_size */
                   valtmp = b->value;
                   break;
   
  
  
  
  1.3       +148 -1    parrot/src/utils.c
  
  Index: utils.c
  ===================================================================
  RCS file: /cvs/public/parrot/src/utils.c,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -w -r1.2 -r1.3
  --- utils.c   23 Oct 2003 17:48:59 -0000      1.2
  +++ utils.c   11 Nov 2003 15:17:20 -0000      1.3
  @@ -1,7 +1,7 @@
   /*  utils.c
    *  Copyright: 2001-2003 The Perl Foundation.  All Rights Reserved.
    *  CVS Info
  - *     $Id: utils.c,v 1.2 2003/10/23 17:48:59 robert Exp $
  + *     $Id: utils.c,v 1.3 2003/11/11 15:17:20 leo Exp $
    *  Overview:
    *     Some utility functions
    *  Data Structure and Algorithms:
  @@ -64,6 +64,153 @@
        ? (n2 - n3 * floor(n2 / n3))
        : n2;
   #endif
  +}
  +
  +/*
  + * currently undefined
  + */
  +#ifndef PARROT_HAS_DRAND48
  +
  +typedef unsigned short _rand_buf[3];
  +/*
  + * s. man drand48, SuS V2
  + *
  + * X(n+1) = ( aX(n) + c ) mod 2^48
  + *
  + */
  +#define A_lo  0xE66D
  +#define A_mid 0xDEEC
  +#define A_hi  0x5
  +#define C     0xB
  +#define SEED_LO 0x330E
  +
  +static _rand_buf a = { A_lo, A_mid, A_hi };
  +static _rand_buf last_rand;
  +static unsigned short c = C;
  +
  +static void
  +next_rand(_rand_buf X)
  +{
  +    unsigned short lo, mid, hi;
  +    unsigned int t;
  +
  +    /* 48 bit mul, one short at a time */
  +    t = X[0] * a[0] + c;
  +    lo = t & 0xffff;
  +    mid = (t >> 16) & 0xffff;
  +
  +    t = X[1] * a[0] + X[0] * a[1] + mid;
  +    mid = t & 0xffff;
  +    hi = (t >> 16) & 0xffff;
  +
  +    t = X[2] * a[0] + X[1] * a[1] + X[0] * a[2] + hi;
  +
  +    X[0] = lo;
  +    X[1] = mid;
  +    X[2] = t & 0xffff;
  +}
  +
  +static FLOATVAL
  +_erand48(_rand_buf buf)
  +{
  +    FLOATVAL r;
  +    next_rand(buf);
  +    r = (( buf[0] / 65536.0 + buf[1] ) / 65536.0 + buf[2]) / 65536.0;
  +    return r;
  +}
  +
  +static FLOATVAL
  +_drand48(void)
  +{
  +    return _erand48(last_rand);
  +}
  +
  +static long
  +_jrand48(_rand_buf buf)
  +{
  +    long ret;
  +    next_rand(buf);
  +    ret = buf[2] << 16 | buf[1];
  +    return ret;
  +}
  +
  +static long
  +_nrand48(_rand_buf buf)
  +{
  +    return _jrand48(buf) & 0x7fffffff;
  +}
  +
  +static long
  +_lrand48(void)
  +{
  +    return _nrand48(last_rand);
  +}
  +
  +static long
  +_mrand48(void)
  +{
  +    return _jrand48(last_rand);
  +}
  +
  +static void
  +_srand48(long seed)
  +{
  +    last_rand[0] = SEED_LO;
  +    last_rand[1] = seed & 0xffff;
  +    last_rand[2] = (seed >> 16) & 0xffff;
  +    /*
  +     * reinit a, c if changed by lcong48()
  +     */
  +}
  +
  +#undef A_lo
  +#undef A_mid
  +#undef A_hi
  +#undef C
  +
  +#else
  +
  +#  define _drand48 drand48
  +#  define _erand48(b) erand48(b)
  +
  +#  define _lrand48 lrand48
  +#  define _nrand48(b) nrand48(b)
  +
  +#  define _mrand48 mrand48
  +#  define _jrand48(b) jrand48(b)
  +
  +#  define _srand48 srand48
  +
  +#endif
  +
  +FLOATVAL
  +Parrot_float_rand(INTVAL how_random)
  +{
  +    return _drand48();          /* [0.0..1.0] */
  +}
  +
  +INTVAL
  +Parrot_uint_rand(INTVAL how_random)
  +{
  +    return _lrand48();          /* [0..2^31] */
  +}
  +
  +INTVAL
  +Parrot_int_rand(INTVAL how_random)
  +{
  +    return _mrand48();          /* [-2^31..2^31] */
  +}
  +
  +INTVAL
  +Parrot_range_rand(INTVAL from, INTVAL to, INTVAL how_random)
  +{
  +    return from + ((double)(to - from)) * Parrot_float_rand(how_random);
  +}
  +
  +void
  +Parrot_srand(INTVAL seed)
  +{
  +    _srand48(seed);
   }
   
   /*
  
  
  

Reply via email to