mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-05-20 11:40:18 +02:00
Fix hashing of vectors to run in bounded time.
* libguile/hash.c (SCM_MIN): New macro. (scm_hasher): In vector case, do nothing if d is 0. Make sure to recurse with a reduced d. Move the loop out of the 'if'.
This commit is contained in:
parent
0e18163366
commit
cc1cd04f81
1 changed files with 30 additions and 26 deletions
|
@ -1,5 +1,5 @@
|
||||||
/* Copyright (C) 1995, 1996, 1997, 2000, 2001, 2003, 2004, 2006, 2008,
|
/* Copyright (C) 1995, 1996, 1997, 2000, 2001, 2003, 2004, 2006, 2008,
|
||||||
* 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
|
* 2009, 2010, 2011, 2012, 2014 Free Software Foundation, Inc.
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public License
|
* modify it under the terms of the GNU Lesser General Public License
|
||||||
|
@ -45,6 +45,7 @@
|
||||||
extern double floor();
|
extern double floor();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define SCM_MIN(A, B) ((A) < (B) ? (A) : (B))
|
||||||
|
|
||||||
unsigned long
|
unsigned long
|
||||||
scm_string_hash (const unsigned char *str, size_t len)
|
scm_string_hash (const unsigned char *str, size_t len)
|
||||||
|
@ -228,31 +229,34 @@ scm_hasher(SCM obj, unsigned long n, size_t d)
|
||||||
return scm_i_struct_hash (obj, n, d);
|
return scm_i_struct_hash (obj, n, d);
|
||||||
case scm_tc7_wvect:
|
case scm_tc7_wvect:
|
||||||
case scm_tc7_vector:
|
case scm_tc7_vector:
|
||||||
{
|
if (d > 0)
|
||||||
size_t len = SCM_SIMPLE_VECTOR_LENGTH (obj);
|
{
|
||||||
if (len > 5)
|
size_t len, i, d2;
|
||||||
{
|
unsigned long h;
|
||||||
size_t i = d/2;
|
|
||||||
unsigned long h = 1;
|
len = SCM_SIMPLE_VECTOR_LENGTH (obj);
|
||||||
while (i--)
|
if (len > 5)
|
||||||
{
|
{
|
||||||
SCM elt = SCM_SIMPLE_VECTOR_REF (obj, h % len);
|
i = d / 2;
|
||||||
h = ((h << 8) + (scm_hasher (elt, n, 2))) % n;
|
h = 1;
|
||||||
}
|
d2 = SCM_MIN (2, d - 1);
|
||||||
return h;
|
}
|
||||||
}
|
else
|
||||||
else
|
{
|
||||||
{
|
i = len;
|
||||||
size_t i = len;
|
h = n - 1;
|
||||||
unsigned long h = (n)-1;
|
d2 = (d - 1) / len;
|
||||||
while (i--)
|
}
|
||||||
{
|
|
||||||
SCM elt = SCM_SIMPLE_VECTOR_REF (obj, h % len);
|
while (i--)
|
||||||
h = ((h << 8) + (scm_hasher (elt, n, d/len))) % n;
|
{
|
||||||
}
|
SCM elt = SCM_SIMPLE_VECTOR_REF (obj, h % len);
|
||||||
return h;
|
h = ((h << 8) + (scm_hasher (elt, n, d2))) % n;
|
||||||
}
|
}
|
||||||
}
|
return h;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return 1;
|
||||||
case scm_tcs_cons_imcar:
|
case scm_tcs_cons_imcar:
|
||||||
case scm_tcs_cons_nimcar:
|
case scm_tcs_cons_nimcar:
|
||||||
if (d) return (scm_hasher (SCM_CAR (obj), n, d/2)
|
if (d) return (scm_hasher (SCM_CAR (obj), n, d/2)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue