Browse Source
bpo-32494: Use gdbm_count for dbm_length if possible (GH-19814)
pull/19837/head
Dong-hee Na
6 years ago
committed by
GitHub
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with
27 additions and
5 deletions
-
Misc/NEWS.d/next/Library/2020-04-30-22-25-08.bpo-32494.1xaU5l.rst
-
Modules/_gdbmmodule.c
|
|
|
@ -0,0 +1,2 @@ |
|
|
|
Update :mod:`dbm.gnu` to use gdbm_count if possible when calling |
|
|
|
:func:`len`. Patch by Dong-hee Na. |
|
|
|
@ -36,7 +36,7 @@ values() methods are not supported."); |
|
|
|
|
|
|
|
typedef struct { |
|
|
|
PyObject_HEAD |
|
|
|
int di_size; /* -1 means recompute */ |
|
|
|
Py_ssize_t di_size; /* -1 means recompute */ |
|
|
|
GDBM_FILE di_dbm; |
|
|
|
} dbmobject; |
|
|
|
|
|
|
|
@ -102,19 +102,39 @@ dbm_length(dbmobject *dp) |
|
|
|
return -1; |
|
|
|
} |
|
|
|
if (dp->di_size < 0) { |
|
|
|
#if GDBM_VERSION_MAJOR >= 1 && GDBM_VERSION_MINOR >= 11 |
|
|
|
errno = 0; |
|
|
|
gdbm_count_t count; |
|
|
|
if (gdbm_count(dp->di_dbm, &count) == -1) { |
|
|
|
if (errno != 0) { |
|
|
|
PyErr_SetFromErrno(DbmError); |
|
|
|
} |
|
|
|
else { |
|
|
|
PyErr_SetString(DbmError, gdbm_strerror(gdbm_errno)); |
|
|
|
} |
|
|
|
return -1; |
|
|
|
} |
|
|
|
if (count > PY_SSIZE_T_MAX) { |
|
|
|
PyErr_SetString(PyExc_OverflowError, "count exceeds PY_SSIZE_T_MAX"); |
|
|
|
return -1; |
|
|
|
} |
|
|
|
dp->di_size = count; |
|
|
|
#else |
|
|
|
datum key,okey; |
|
|
|
int size; |
|
|
|
okey.dsize=0; |
|
|
|
okey.dptr=NULL; |
|
|
|
|
|
|
|
size = 0; |
|
|
|
for (key=gdbm_firstkey(dp->di_dbm); key.dptr; |
|
|
|
Py_ssize_t size = 0; |
|
|
|
for (key = gdbm_firstkey(dp->di_dbm); key.dptr; |
|
|
|
key = gdbm_nextkey(dp->di_dbm,okey)) { |
|
|
|
size++; |
|
|
|
if(okey.dsize) free(okey.dptr); |
|
|
|
if (okey.dsize) { |
|
|
|
free(okey.dptr); |
|
|
|
} |
|
|
|
okey=key; |
|
|
|
} |
|
|
|
dp->di_size = size; |
|
|
|
#endif |
|
|
|
} |
|
|
|
return dp->di_size; |
|
|
|
} |
|
|
|
|