mirror of
https://github.com/python/cpython.git
synced 2025-07-24 11:44:31 +00:00
String interning.
This commit is contained in:
parent
ee5cf9b672
commit
2a61e7428d
3 changed files with 287 additions and 34 deletions
|
@ -87,6 +87,9 @@ typedef struct {
|
|||
int ma_fill;
|
||||
int ma_used;
|
||||
int ma_size;
|
||||
#ifdef INTERN_STRINGS
|
||||
int ma_fast;
|
||||
#endif
|
||||
mappingentry *ma_table;
|
||||
} mappingobject;
|
||||
|
||||
|
@ -106,6 +109,9 @@ newmappingobject()
|
|||
mp->ma_table = NULL;
|
||||
mp->ma_fill = 0;
|
||||
mp->ma_used = 0;
|
||||
#ifdef INTERN_STRINGS
|
||||
mp->ma_fast = 1;
|
||||
#endif
|
||||
return (object *)mp;
|
||||
}
|
||||
|
||||
|
@ -163,17 +169,40 @@ lookmapping(mp, key, hash)
|
|||
unsigned long sum;
|
||||
int incr;
|
||||
int size;
|
||||
#ifdef INTERN_STRINGS
|
||||
int fast;
|
||||
#endif
|
||||
|
||||
ep = &mp->ma_table[(unsigned long)hash%mp->ma_size];
|
||||
ekey = ep->me_key;
|
||||
if (ekey == NULL)
|
||||
return ep;
|
||||
#ifdef INTERN_STRINGS
|
||||
if ((fast = mp->ma_fast)) {
|
||||
object *ikey;
|
||||
if (!is_stringobject(key) ||
|
||||
(ikey = ((stringobject *)key)->ob_sinterned) == NULL)
|
||||
fast = 0;
|
||||
else
|
||||
key = ikey;
|
||||
}
|
||||
#endif
|
||||
if (ekey == dummy)
|
||||
freeslot = ep;
|
||||
else if (ep->me_hash == hash && cmpobject(ekey, key) == 0)
|
||||
return ep;
|
||||
else
|
||||
else {
|
||||
#ifdef INTERN_STRINGS
|
||||
if (fast) {
|
||||
if (ekey == key)
|
||||
return ep;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
if (ep->me_hash == hash && cmpobject(ekey, key) == 0)
|
||||
return ep;
|
||||
}
|
||||
freeslot = NULL;
|
||||
}
|
||||
|
||||
size = mp->ma_size;
|
||||
sum = hash;
|
||||
|
@ -184,6 +213,36 @@ lookmapping(mp, key, hash)
|
|||
|
||||
end = mp->ma_table + size;
|
||||
|
||||
#ifdef INTERN_STRINGS
|
||||
if (fast) {
|
||||
if (freeslot == NULL) {
|
||||
for (;;) {
|
||||
ep += incr;
|
||||
if (ep >= end)
|
||||
ep -= size;
|
||||
ekey = ep->me_key;
|
||||
if (ekey == NULL || ekey == key)
|
||||
return ep;
|
||||
if (ekey == dummy) {
|
||||
freeslot = ep;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
ep += incr;
|
||||
if (ep >= end)
|
||||
ep -= size;
|
||||
ekey = ep->me_key;
|
||||
if (ekey == NULL)
|
||||
return freeslot;
|
||||
if (ekey == key)
|
||||
return ep;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (freeslot == NULL) {
|
||||
for (;;) {
|
||||
ep += incr;
|
||||
|
@ -339,13 +398,35 @@ mappinginsert(op, key, value)
|
|||
err_badcall();
|
||||
return -1;
|
||||
}
|
||||
#ifdef CACHE_HASH
|
||||
if (!is_stringobject(key) || (hash = ((stringobject *) key)->ob_shash) == -1)
|
||||
#endif
|
||||
hash = hashobject(key);
|
||||
if (hash == -1)
|
||||
return -1;
|
||||
mp = (mappingobject *)op;
|
||||
#ifdef CACHE_HASH
|
||||
if (is_stringobject(key)) {
|
||||
#ifdef INTERN_STRINGS
|
||||
if (((stringobject *)key)->ob_sinterned != NULL) {
|
||||
key = ((stringobject *)key)->ob_sinterned;
|
||||
hash = ((stringobject *)key)->ob_shash;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
hash = ((stringobject *)key)->ob_shash;
|
||||
if (hash == -1)
|
||||
hash = hashobject(key);
|
||||
#ifdef INTERN_STRINGS
|
||||
mp->ma_fast = 0;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
hash = hashobject(key);
|
||||
if (hash == -1)
|
||||
return -1;
|
||||
#ifdef INTERN_STRINGS
|
||||
mp->ma_fast = 0;
|
||||
#endif
|
||||
}
|
||||
/* if fill >= 2/3 size, resize */
|
||||
if (mp->ma_fill*3 >= mp->ma_size*2) {
|
||||
if (mappingresize(mp) != 0) {
|
||||
|
@ -907,16 +988,22 @@ setattro(v, name, value)
|
|||
object *name;
|
||||
object *value;
|
||||
{
|
||||
int err;
|
||||
INCREF(name);
|
||||
PyString_InternInPlace(&name);
|
||||
if (v->ob_type->tp_setattro != NULL)
|
||||
return (*v->ob_type->tp_setattro)(v, name, value);
|
||||
|
||||
if (name != last_name_object) {
|
||||
XDECREF(last_name_object);
|
||||
INCREF(name);
|
||||
last_name_object = name;
|
||||
last_name_char = getstringvalue(name);
|
||||
err = (*v->ob_type->tp_setattro)(v, name, value);
|
||||
else {
|
||||
if (name != last_name_object) {
|
||||
XDECREF(last_name_object);
|
||||
INCREF(name);
|
||||
last_name_object = name;
|
||||
last_name_char = getstringvalue(name);
|
||||
}
|
||||
err = setattr(v, last_name_char, value);
|
||||
}
|
||||
return setattr(v, last_name_char, value);
|
||||
DECREF(name);
|
||||
return err;
|
||||
}
|
||||
|
||||
object *
|
||||
|
@ -931,6 +1018,7 @@ dictlookup(v, key)
|
|||
last_name_char = NULL;
|
||||
return NULL;
|
||||
}
|
||||
PyString_InternInPlace(&last_name_object);
|
||||
last_name_char = getstringvalue(last_name_object);
|
||||
}
|
||||
return mappinglookup(v, last_name_object);
|
||||
|
@ -949,6 +1037,7 @@ dictinsert(v, key, item)
|
|||
last_name_char = NULL;
|
||||
return -1;
|
||||
}
|
||||
PyString_InternInPlace(&last_name_object);
|
||||
last_name_char = getstringvalue(last_name_object);
|
||||
}
|
||||
return mappinginsert(v, last_name_object, item);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue