mirror of
https://github.com/python/cpython.git
synced 2025-07-24 11:44:31 +00:00
bpo-40602: Write unit tests for _Py_hashtable_t (GH-20091)
Cleanup also hashtable.c. Rename _Py_hashtable_t members: * Rename entries to nentries * Rename num_buckets to nbuckets
This commit is contained in:
parent
f2c3b6823b
commit
a482dc500b
4 changed files with 151 additions and 120 deletions
|
@ -14,6 +14,7 @@
|
|||
#include "Python.h"
|
||||
#include "pycore_byteswap.h" // _Py_bswap32()
|
||||
#include "pycore_initconfig.h" // _Py_GetConfigsAsDict()
|
||||
#include "pycore_hashtable.h" // _Py_hashtable_new()
|
||||
#include "pycore_gc.h" // PyGC_Head
|
||||
|
||||
|
||||
|
@ -62,10 +63,97 @@ test_bswap(PyObject *self, PyObject *Py_UNUSED(args))
|
|||
}
|
||||
|
||||
|
||||
#define TO_PTR(ch) ((void*)(uintptr_t)ch)
|
||||
#define FROM_PTR(ptr) ((uintptr_t)ptr)
|
||||
#define VALUE(key) (1 + ((int)(key) - 'a'))
|
||||
|
||||
static Py_uhash_t
|
||||
hash_char(const void *key)
|
||||
{
|
||||
char ch = (char)FROM_PTR(key);
|
||||
return ch;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
hashtable_cb(_Py_hashtable_t *table,
|
||||
const void *key_ptr, const void *value_ptr,
|
||||
void *user_data)
|
||||
{
|
||||
int *count = (int *)user_data;
|
||||
char key = (char)FROM_PTR(key_ptr);
|
||||
int value = (int)FROM_PTR(value_ptr);
|
||||
assert(value == VALUE(key));
|
||||
*count += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static PyObject*
|
||||
test_hashtable(PyObject *self, PyObject *Py_UNUSED(args))
|
||||
{
|
||||
_Py_hashtable_t *table = _Py_hashtable_new(hash_char,
|
||||
_Py_hashtable_compare_direct);
|
||||
if (table == NULL) {
|
||||
return PyErr_NoMemory();
|
||||
}
|
||||
|
||||
// Test _Py_hashtable_set()
|
||||
char key;
|
||||
for (key='a'; key <= 'z'; key++) {
|
||||
int value = VALUE(key);
|
||||
if (_Py_hashtable_set(table, TO_PTR(key), TO_PTR(value)) < 0) {
|
||||
_Py_hashtable_destroy(table);
|
||||
return PyErr_NoMemory();
|
||||
}
|
||||
}
|
||||
assert(table->nentries == 26);
|
||||
assert(table->nbuckets > table->nentries);
|
||||
|
||||
// Test _Py_hashtable_get_entry()
|
||||
for (key='a'; key <= 'z'; key++) {
|
||||
_Py_hashtable_entry_t *entry = _Py_hashtable_get_entry(table, TO_PTR(key));
|
||||
assert(entry != NULL);
|
||||
assert(entry->key = TO_PTR(key));
|
||||
assert(entry->value = TO_PTR(VALUE(key)));
|
||||
}
|
||||
|
||||
// Test _Py_hashtable_get()
|
||||
for (key='a'; key <= 'z'; key++) {
|
||||
void *value_ptr = _Py_hashtable_get(table, TO_PTR(key));
|
||||
int value = (int)FROM_PTR(value_ptr);
|
||||
assert(value == VALUE(key));
|
||||
}
|
||||
|
||||
// Test _Py_hashtable_steal()
|
||||
key = 'p';
|
||||
void *value_ptr = _Py_hashtable_steal(table, TO_PTR(key));
|
||||
int value = (int)FROM_PTR(value_ptr);
|
||||
assert(value == VALUE(key));
|
||||
|
||||
assert(table->nentries == 25);
|
||||
|
||||
// Test _Py_hashtable_foreach()
|
||||
int count = 0;
|
||||
int res = _Py_hashtable_foreach(table, hashtable_cb, &count);
|
||||
assert(res == 0);
|
||||
assert(count == 25);
|
||||
|
||||
// Test _Py_hashtable_clear()
|
||||
_Py_hashtable_clear(table);
|
||||
assert(table->nentries == 0);
|
||||
assert(_Py_hashtable_get(table, TO_PTR('x')) == NULL);
|
||||
|
||||
_Py_hashtable_destroy(table);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
|
||||
static PyMethodDef TestMethods[] = {
|
||||
{"get_configs", get_configs, METH_NOARGS},
|
||||
{"get_recursion_depth", get_recursion_depth, METH_NOARGS},
|
||||
{"test_bswap", test_bswap, METH_NOARGS},
|
||||
{"test_hashtable", test_hashtable, METH_NOARGS},
|
||||
{NULL, NULL} /* sentinel */
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue