1 |
/* Copyright (C) 1995,1996,1997,1998,2000,2001 Free Software Foundation, Inc. |
/* Copyright (C) 1995,1996,1997,1998,2000,2001, 2003 Free Software Foundation, Inc. |
2 |
* |
* |
3 |
* This program is free software; you can redistribute it and/or modify |
* This program is free software; you can redistribute it and/or modify |
4 |
* it under the terms of the GNU General Public License as published by |
* it under the terms of the GNU General Public License as published by |
83 |
/* {Symbols} |
/* {Symbols} |
84 |
*/ |
*/ |
85 |
|
|
86 |
|
/* In order to optimize reading speed, this function breaks part of |
87 |
|
* the hashtable abstraction. The optimizations are: |
88 |
|
* |
89 |
|
* 1. The argument string can be compared directly to symbol objects |
90 |
|
* without first creating an SCM string object. (This would have |
91 |
|
* been necessary if we had used the hashtable API in hashtab.h.) |
92 |
|
* |
93 |
|
* 2. We can use the raw hash value stored in SCM_SYMBOL_HASH (sym) |
94 |
|
* to speed up lookup. |
95 |
|
* |
96 |
|
* Both optimizations might be possible without breaking the |
97 |
|
* abstraction if the API in hashtab.c is improved. |
98 |
|
*/ |
99 |
|
|
100 |
|
unsigned long |
101 |
|
scm_i_hash_symbol (SCM obj, unsigned long n, void *closure) |
102 |
|
{ |
103 |
|
return SCM_SYMBOL_HASH (obj) % n; |
104 |
|
} |
105 |
|
|
106 |
SCM |
SCM |
107 |
scm_mem2symbol (const char *name, size_t len) |
scm_mem2symbol (const char *name, size_t len) |
108 |
{ |
{ |
109 |
size_t raw_hash = scm_string_hash ((const unsigned char *) name, len)/2; |
size_t raw_hash = scm_string_hash ((const unsigned char *) name, len) / 2; |
110 |
size_t hash = raw_hash % SCM_VECTOR_LENGTH (symbols); |
size_t hash = raw_hash % SCM_HASHTABLE_N_BUCKETS (symbols); |
111 |
|
|
112 |
{ |
{ |
113 |
/* Try to find the symbol in the symbols table */ |
/* Try to find the symbol in the symbols table */ |
114 |
|
|
115 |
SCM l; |
SCM l; |
116 |
|
|
117 |
for (l = SCM_VELTS (symbols) [hash]; !SCM_NULLP (l); l = SCM_CDR (l)) |
for (l = SCM_HASHTABLE_BUCKETS (symbols) [hash]; |
118 |
|
!SCM_NULLP (l); |
119 |
|
l = SCM_CDR (l)) |
120 |
{ |
{ |
121 |
SCM sym = SCM_CAAR (l); |
SCM sym = SCM_CAAR (l); |
122 |
if (SCM_SYMBOL_HASH (sym) == raw_hash |
if (SCM_SYMBOL_HASH (sym) == raw_hash |
147 |
raw_hash, |
raw_hash, |
148 |
SCM_UNPACK (scm_cons (SCM_BOOL_F, SCM_EOL))); |
SCM_UNPACK (scm_cons (SCM_BOOL_F, SCM_EOL))); |
149 |
|
|
150 |
SCM slot = SCM_VELTS (symbols) [hash]; |
SCM slot = SCM_HASHTABLE_BUCKETS (symbols) [hash]; |
151 |
SCM cell = scm_cons (symbol, SCM_UNDEFINED); |
SCM cell = scm_cons (symbol, SCM_UNDEFINED); |
152 |
SCM_VECTOR_SET (symbols, hash, scm_cons (cell, slot)); |
SCM_SET_HASHTABLE_BUCKET (symbols, hash, scm_cons (cell, slot)); |
153 |
|
SCM_HASHTABLE_INCREMENT (symbols); |
154 |
|
if (SCM_HASHTABLE_N_ITEMS (symbols) > SCM_HASHTABLE_UPPER (symbols)) |
155 |
|
scm_i_rehash (symbols, scm_i_hash_symbol, 0, "scm_mem2symbol"); |
156 |
|
|
157 |
return symbol; |
return symbol; |
158 |
} |
} |