Skip to content

Commit 5db556b

Browse files
committed
refactor to avoid storing a packed string on the descr
1 parent e30542d commit 5db556b

File tree

2 files changed

+19
-63
lines changed

2 files changed

+19
-63
lines changed

stringdtype/stringdtype/src/dtype.c

Lines changed: 19 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ new_stringdtype_instance(PyObject *na_object, int coerce)
2121
npy_string_allocator *allocator = NULL;
2222
PyThread_type_lock *allocator_lock = NULL;
2323

24+
char *default_string_buf = NULL;
25+
char *na_name_buf = NULL;
26+
2427
allocator = NpyString_new_allocator(PyMem_RawMalloc, PyMem_RawFree,
2528
PyMem_RawRealloc);
2629
if (allocator == NULL) {
@@ -35,12 +38,8 @@ new_stringdtype_instance(PyObject *na_object, int coerce)
3538
goto fail;
3639
}
3740

38-
char packed_na_name[SIZEOF_NPY_PACKED_STATIC_STRING] = {0};
39-
NpyString_pack(allocator, (npy_packed_static_string *)&packed_na_name, "",
40-
0);
41-
char packed_default_string[SIZEOF_NPY_PACKED_STATIC_STRING] = {0};
42-
NpyString_pack(allocator,
43-
(npy_packed_static_string *)&packed_default_string, "", 0);
41+
npy_static_string default_string = {0, NULL};
42+
npy_static_string na_name = {0, NULL};
4443

4544
Py_XINCREF(na_object);
4645
((StringDTypeObject *)new)->na_object = na_object;
@@ -53,15 +52,9 @@ new_stringdtype_instance(PyObject *na_object, int coerce)
5352
has_string_na = 1;
5453
Py_ssize_t size = 0;
5554
const char *buf = PyUnicode_AsUTF8AndSize(na_object, &size);
56-
if (NpyString_newsize(
57-
buf, (size_t)size,
58-
(npy_packed_static_string *)&packed_default_string,
59-
allocator) < 0) {
60-
PyErr_SetString(PyExc_MemoryError,
61-
"Failed to allocate string while creating "
62-
"StringDType instance.");
63-
goto fail;
64-
}
55+
default_string.buf = PyMem_RawMalloc(size);
56+
memcpy((char *)default_string.buf, buf, size);
57+
default_string.size = size;
6558
}
6659
else {
6760
// treat as nan-like if != comparison returns a object whose truth
@@ -92,55 +85,20 @@ new_stringdtype_instance(PyObject *na_object, int coerce)
9285
Py_DECREF(na_pystr);
9386
goto fail;
9487
}
95-
if (NpyString_newsize(utf8_ptr, (size_t)size,
96-
(npy_packed_static_string *)&packed_na_name,
97-
allocator) < 0) {
98-
PyErr_SetString(PyExc_MemoryError,
99-
"Failed to allocate string while creating "
100-
"StringDType instance.");
101-
Py_DECREF(na_pystr);
102-
goto fail;
103-
}
88+
na_name.buf = PyMem_RawMalloc(size);
89+
memcpy((char *)na_name.buf, utf8_ptr, size);
90+
na_name.size = size;
10491
Py_DECREF(na_pystr);
10592
}
10693

10794
StringDTypeObject *snew = (StringDTypeObject *)new;
10895

10996
snew->has_nan_na = has_nan_na;
11097
snew->has_string_na = has_string_na;
111-
memcpy(snew->packed_default_string, packed_default_string,
112-
SIZEOF_NPY_PACKED_STATIC_STRING);
113-
memcpy(snew->packed_na_name, packed_na_name,
114-
SIZEOF_NPY_PACKED_STATIC_STRING);
11598
snew->coerce = coerce;
11699
snew->allocator_lock = allocator_lock;
117100
snew->allocator = allocator;
118101
snew->array_owned = 0;
119-
120-
npy_static_string default_string = {0, NULL};
121-
if (NpyString_load(
122-
allocator,
123-
(npy_packed_static_string *)&snew->packed_default_string,
124-
&default_string) == -1) {
125-
PyErr_SetString(PyExc_MemoryError,
126-
"Failed to load packed string while "
127-
"creating StringDType instance.");
128-
Py_DECREF(snew);
129-
return NULL;
130-
}
131-
132-
npy_static_string na_name = {0, NULL};
133-
if (NpyString_load(allocator,
134-
(npy_packed_static_string *)&snew->packed_na_name,
135-
&na_name) == -1) {
136-
PyErr_SetString(PyExc_MemoryError,
137-
"Failed to load packed string while "
138-
"creating StringDType instance.");
139-
140-
Py_DECREF(snew);
141-
return NULL;
142-
}
143-
144102
snew->na_name = na_name;
145103
snew->default_string = default_string;
146104

@@ -162,10 +120,13 @@ new_stringdtype_instance(PyObject *na_object, int coerce)
162120
fail:
163121
// this only makes sense if the allocator isn't attached to new yet
164122
Py_DECREF(new);
123+
if (default_string_buf != NULL) {
124+
PyMem_RawFree(default_string_buf);
125+
}
126+
if (na_name_buf != NULL) {
127+
PyMem_RawFree(na_name_buf);
128+
}
165129
if (allocator != NULL) {
166-
NpyString_free((npy_packed_static_string *)&packed_na_name, allocator);
167-
NpyString_free((npy_packed_static_string *)&packed_default_string,
168-
allocator);
169130
NpyString_free_allocator(allocator);
170131
}
171132
if (allocator_lock != NULL) {
@@ -713,14 +674,11 @@ stringdtype_dealloc(StringDTypeObject *self)
713674
if (self->allocator != NULL) {
714675
// can we assume the destructor for an instance will only get called
715676
// inside of one C thread?
716-
NpyString_free(
717-
(npy_packed_static_string *)&self->packed_default_string,
718-
self->allocator);
719-
NpyString_free((npy_packed_static_string *)&self->packed_na_name,
720-
self->allocator);
721677
NpyString_free_allocator(self->allocator);
722678
PyThread_free_lock(self->allocator_lock);
723679
}
680+
PyMem_RawFree((char *)self->na_name.buf);
681+
PyMem_RawFree((char *)self->default_string.buf);
724682
PyArrayDescr_Type.tp_dealloc((PyObject *)self);
725683
}
726684

stringdtype/stringdtype/src/dtype.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,7 @@ typedef struct {
7171
int has_string_na;
7272
int array_owned;
7373
npy_static_string default_string;
74-
char packed_default_string[SIZEOF_NPY_PACKED_STATIC_STRING];
7574
npy_static_string na_name;
76-
char packed_na_name[SIZEOF_NPY_PACKED_STATIC_STRING];
7775
PyThread_type_lock *allocator_lock;
7876
// the allocator should only be directly accessed after
7977
// acquiring the allocator_lock and the lock should

0 commit comments

Comments
 (0)