summaryrefslogtreecommitdiffstats
path: root/Objects/stringobject.c
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>1997-01-18 07:55:05 (GMT)
committerGuido van Rossum <guido@python.org>1997-01-18 07:55:05 (GMT)
commit2a61e7428d5b45fe778b7766bb623d780162f402 (patch)
treec076925be369b28db2cbba5d19e8436ebca8c3bd /Objects/stringobject.c
parentee5cf9b672b8e919ca9d425d88aedb2c4614772f (diff)
downloadcpython-2a61e7428d5b45fe778b7766bb623d780162f402.zip
cpython-2a61e7428d5b45fe778b7766bb623d780162f402.tar.gz
cpython-2a61e7428d5b45fe778b7766bb623d780162f402.tar.bz2
String interning.
Diffstat (limited to 'Objects/stringobject.c')
-rw-r--r--Objects/stringobject.c75
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