diff options
author | Guido van Rossum <guido@python.org> | 1997-01-18 07:55:05 (GMT) |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 1997-01-18 07:55:05 (GMT) |
commit | 2a61e7428d5b45fe778b7766bb623d780162f402 (patch) | |
tree | c076925be369b28db2cbba5d19e8436ebca8c3bd /Objects/stringobject.c | |
parent | ee5cf9b672b8e919ca9d425d88aedb2c4614772f (diff) | |
download | cpython-2a61e7428d5b45fe778b7766bb623d780162f402.zip cpython-2a61e7428d5b45fe778b7766bb623d780162f402.tar.gz cpython-2a61e7428d5b45fe778b7766bb623d780162f402.tar.bz2 |
String interning.
Diffstat (limited to 'Objects/stringobject.c')
-rw-r--r-- | Objects/stringobject.c | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/Objects/stringobject.c b/Objects/stringobject.c index 048b83c..d656fa1 100644 --- a/Objects/stringobject.c +++ b/Objects/stringobject.c @@ -98,6 +98,9 @@ newsizedstringobject(str, size) #ifdef CACHE_HASH op->ob_shash = -1; #endif +#ifdef INTERN_STRINGS + op->ob_sinterned = NULL; +#endif NEWREF(op); if (str != NULL) memcpy(op->ob_sval, str, size); @@ -145,6 +148,9 @@ newstringobject(str) #ifdef CACHE_HASH op->ob_shash = -1; #endif +#ifdef INTERN_STRINGS + op->ob_sinterned = NULL; +#endif NEWREF(op); strcpy(op->ob_sval, str); #ifndef DONT_SHARE_SHORT_STRINGS @@ -304,6 +310,9 @@ string_concat(a, bb) #ifdef CACHE_HASH op->ob_shash = -1; #endif +#ifdef INTERN_STRINGS + op->ob_sinterned = NULL; +#endif NEWREF(op); memcpy(op->ob_sval, a->ob_sval, (int) a->ob_size); memcpy(op->ob_sval + a->ob_size, b->ob_sval, (int) b->ob_size); @@ -336,6 +345,9 @@ string_repeat(a, n) #ifdef CACHE_HASH op->ob_shash = -1; #endif +#ifdef INTERN_STRINGS + op->ob_sinterned = NULL; +#endif NEWREF(op); for (i = 0; i < size; i += a->ob_size) memcpy(op->ob_sval+i, a->ob_sval, (int) a->ob_size); @@ -462,6 +474,13 @@ typeobject Stringtype = { &string_as_sequence, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ (hashfunc)string_hash, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_xxx3*/ + 0, /*tp_xxx4*/ + 0, /*tp_doc*/ }; void @@ -928,3 +947,59 @@ formatstring(format, args) DECREF(args); return NULL; } + + +#ifdef INTERN_STRINGS + +static PyObject *interned; + +void +PyString_InternInPlace(p) + PyObject **p; +{ + register PyStringObject *s = (PyStringObject *)(*p); + PyObject *t; + if (s == NULL || !PyString_Check(s)) + Py_FatalError("PyString_InternInPlace: strings only please!"); + if ((t = s->ob_sinterned) != NULL) { + if (t == (PyObject *)s) + return; + Py_INCREF(t); + *p = t; + Py_DECREF(s); + return; + } + if (interned == NULL) { + interned = PyDict_New(); + if (interned == NULL) + return; + /* Force slow lookups: */ + PyDict_SetItem(interned, Py_None, Py_None); + } + if ((t = PyDict_GetItem(interned, (PyObject *)s)) != NULL) { + Py_INCREF(t); + *p = s->ob_sinterned = t; + Py_DECREF(s); + return; + } + t = (PyObject *)s; + if (PyDict_SetItem(interned, t, t) == 0) { + s->ob_sinterned = t; + return; + } + PyErr_Clear(); +} + + +PyObject * +PyString_InternFromString(cp) + const char *cp; +{ + PyObject *s = PyString_FromString(cp); + if (s == NULL) + return NULL; + PyString_InternInPlace(&s); + return s; +} + +#endif |