mirror of
https://gitlab.com/embeddable-common-lisp/ecl.git
synced 2026-04-27 19:50:44 -07:00
Improved hashing of unicode strings
This commit is contained in:
parent
4b8f0de401
commit
e83d8282ed
4 changed files with 43 additions and 17 deletions
|
|
@ -39,6 +39,8 @@ ECL 0.9k:
|
|||
collisions between files compiled on different machines. In short: you should
|
||||
only worry if you regularly use the function C::BUILD.
|
||||
|
||||
- Improved hashing of unicode strings.
|
||||
|
||||
* CLOS:
|
||||
|
||||
- When caching generic function calls, ECL now uses a thread-local hash table
|
||||
|
|
|
|||
20
src/c/hash.d
20
src/c/hash.d
|
|
@ -84,22 +84,10 @@ _hash_equal(int depth, cl_hashkey h, cl_object x)
|
|||
case t_symbol:
|
||||
x = x->symbol.name;
|
||||
#ifdef ECL_UNICODE
|
||||
case t_base_string: {
|
||||
cl_index i;
|
||||
for (i = 0; i < x->base_string.fillp; i++) {
|
||||
cl_index w = x->base_string.self[i];
|
||||
h = hash_word(h, w);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case t_string: {
|
||||
cl_index i;
|
||||
for (i = 0; i < x->string.fillp; i++) {
|
||||
cl_index w = CHAR_CODE(x->string.self[i]);
|
||||
h = hash_word(h, w);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case t_base_string:
|
||||
return hash_base_string(x->base_string.self, x->base_string.fillp, h);
|
||||
case t_string:
|
||||
return hash_full_string(x->base_string.self, x->base_string.fillp, h);
|
||||
#else
|
||||
case t_base_string:
|
||||
return hash_string(h, x->base_string.self, x->base_string.fillp);
|
||||
|
|
|
|||
|
|
@ -145,3 +145,39 @@ static cl_index hash_word(cl_index c, cl_index a)
|
|||
return c;
|
||||
}
|
||||
|
||||
static cl_index hash_base_string(const char *s, cl_index len, cl_index h)
|
||||
{
|
||||
cl_index a = GOLDEN_RATIO, b = GOLDEN_RATIO, i;
|
||||
for (i = len; i >= 3; i -= 3) {
|
||||
a += *s; s++;
|
||||
b += *s; s++;
|
||||
h += *s; s++;
|
||||
mix(a, b, h);
|
||||
}
|
||||
switch (i) {
|
||||
case 2: a += *s; s++;
|
||||
case 1: b += *s;
|
||||
default: h += len;
|
||||
}
|
||||
mix(a, b, h);
|
||||
return h;
|
||||
}
|
||||
|
||||
static cl_index hash_full_string(const cl_object *s, cl_index len, cl_index h)
|
||||
{
|
||||
cl_index a = GOLDEN_RATIO, b = GOLDEN_RATIO, i;
|
||||
for (i = len; i >= 3; i -= 3) {
|
||||
a += CHAR_CODE(*s); s++;
|
||||
b += CHAR_CODE(*s); s++;
|
||||
h += CHAR_CODE(*s); s++;
|
||||
mix(a, b, h);
|
||||
}
|
||||
switch (i) {
|
||||
case 2: a += CHAR_CODE(*s); s++;
|
||||
case 1: b += CHAR_CODE(*s);
|
||||
default: h += len;
|
||||
}
|
||||
mix(a, b, h);
|
||||
return h;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ Returns, as a string, the location of the machine on which ECL runs."
|
|||
(defun lisp-implementation-version ()
|
||||
"Args:()
|
||||
Returns the version of your ECL as a string."
|
||||
"@PACKAGE_VERSION@ (CVS 2008-02-01 14:01)")
|
||||
"@PACKAGE_VERSION@ (CVS 2008-02-01 20:07)")
|
||||
|
||||
(defun machine-type ()
|
||||
"Args: ()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue