mirror of
				https://github.com/python/cpython.git
				synced 2025-11-03 19:34:08 +00:00 
			
		
		
		
	Add a new _Py_HashPointerRaw() function which avoids replacing -1 with -2 to micro-optimize hash table using pointer keys: using _Py_hashtable_hash_ptr() hash function.
		
			
				
	
	
		
			147 lines
		
	
	
	
		
			4.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			147 lines
		
	
	
	
		
			4.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
#ifndef Py_HASH_H
 | 
						|
 | 
						|
#define Py_HASH_H
 | 
						|
#ifdef __cplusplus
 | 
						|
extern "C" {
 | 
						|
#endif
 | 
						|
 | 
						|
/* Helpers for hash functions */
 | 
						|
#ifndef Py_LIMITED_API
 | 
						|
PyAPI_FUNC(Py_hash_t) _Py_HashDouble(double);
 | 
						|
PyAPI_FUNC(Py_hash_t) _Py_HashPointer(const void*);
 | 
						|
// Similar to _Py_HashPointer(), but don't replace -1 with -2
 | 
						|
PyAPI_FUNC(Py_hash_t) _Py_HashPointerRaw(const void*);
 | 
						|
PyAPI_FUNC(Py_hash_t) _Py_HashBytes(const void*, Py_ssize_t);
 | 
						|
#endif
 | 
						|
 | 
						|
/* Prime multiplier used in string and various other hashes. */
 | 
						|
#define _PyHASH_MULTIPLIER 1000003UL  /* 0xf4243 */
 | 
						|
 | 
						|
/* Parameters used for the numeric hash implementation.  See notes for
 | 
						|
   _Py_HashDouble in Python/pyhash.c.  Numeric hashes are based on
 | 
						|
   reduction modulo the prime 2**_PyHASH_BITS - 1. */
 | 
						|
 | 
						|
#if SIZEOF_VOID_P >= 8
 | 
						|
#  define _PyHASH_BITS 61
 | 
						|
#else
 | 
						|
#  define _PyHASH_BITS 31
 | 
						|
#endif
 | 
						|
 | 
						|
#define _PyHASH_MODULUS (((size_t)1 << _PyHASH_BITS) - 1)
 | 
						|
#define _PyHASH_INF 314159
 | 
						|
#define _PyHASH_NAN 0
 | 
						|
#define _PyHASH_IMAG _PyHASH_MULTIPLIER
 | 
						|
 | 
						|
 | 
						|
/* hash secret
 | 
						|
 *
 | 
						|
 * memory layout on 64 bit systems
 | 
						|
 *   cccccccc cccccccc cccccccc  uc -- unsigned char[24]
 | 
						|
 *   pppppppp ssssssss ........  fnv -- two Py_hash_t
 | 
						|
 *   k0k0k0k0 k1k1k1k1 ........  siphash -- two uint64_t
 | 
						|
 *   ........ ........ ssssssss  djbx33a -- 16 bytes padding + one Py_hash_t
 | 
						|
 *   ........ ........ eeeeeeee  pyexpat XML hash salt
 | 
						|
 *
 | 
						|
 * memory layout on 32 bit systems
 | 
						|
 *   cccccccc cccccccc cccccccc  uc
 | 
						|
 *   ppppssss ........ ........  fnv -- two Py_hash_t
 | 
						|
 *   k0k0k0k0 k1k1k1k1 ........  siphash -- two uint64_t (*)
 | 
						|
 *   ........ ........ ssss....  djbx33a -- 16 bytes padding + one Py_hash_t
 | 
						|
 *   ........ ........ eeee....  pyexpat XML hash salt
 | 
						|
 *
 | 
						|
 * (*) The siphash member may not be available on 32 bit platforms without
 | 
						|
 *     an unsigned int64 data type.
 | 
						|
 */
 | 
						|
#ifndef Py_LIMITED_API
 | 
						|
typedef union {
 | 
						|
    /* ensure 24 bytes */
 | 
						|
    unsigned char uc[24];
 | 
						|
    /* two Py_hash_t for FNV */
 | 
						|
    struct {
 | 
						|
        Py_hash_t prefix;
 | 
						|
        Py_hash_t suffix;
 | 
						|
    } fnv;
 | 
						|
    /* two uint64 for SipHash24 */
 | 
						|
    struct {
 | 
						|
        uint64_t k0;
 | 
						|
        uint64_t k1;
 | 
						|
    } siphash;
 | 
						|
    /* a different (!) Py_hash_t for small string optimization */
 | 
						|
    struct {
 | 
						|
        unsigned char padding[16];
 | 
						|
        Py_hash_t suffix;
 | 
						|
    } djbx33a;
 | 
						|
    struct {
 | 
						|
        unsigned char padding[16];
 | 
						|
        Py_hash_t hashsalt;
 | 
						|
    } expat;
 | 
						|
} _Py_HashSecret_t;
 | 
						|
PyAPI_DATA(_Py_HashSecret_t) _Py_HashSecret;
 | 
						|
#endif
 | 
						|
 | 
						|
#ifdef Py_DEBUG
 | 
						|
PyAPI_DATA(int) _Py_HashSecret_Initialized;
 | 
						|
#endif
 | 
						|
 | 
						|
 | 
						|
/* hash function definition */
 | 
						|
#ifndef Py_LIMITED_API
 | 
						|
typedef struct {
 | 
						|
    Py_hash_t (*const hash)(const void *, Py_ssize_t);
 | 
						|
    const char *name;
 | 
						|
    const int hash_bits;
 | 
						|
    const int seed_bits;
 | 
						|
} PyHash_FuncDef;
 | 
						|
 | 
						|
PyAPI_FUNC(PyHash_FuncDef*) PyHash_GetFuncDef(void);
 | 
						|
#endif
 | 
						|
 | 
						|
 | 
						|
/* cutoff for small string DJBX33A optimization in range [1, cutoff).
 | 
						|
 *
 | 
						|
 * About 50% of the strings in a typical Python application are smaller than
 | 
						|
 * 6 to 7 chars. However DJBX33A is vulnerable to hash collision attacks.
 | 
						|
 * NEVER use DJBX33A for long strings!
 | 
						|
 *
 | 
						|
 * A Py_HASH_CUTOFF of 0 disables small string optimization. 32 bit platforms
 | 
						|
 * should use a smaller cutoff because it is easier to create colliding
 | 
						|
 * strings. A cutoff of 7 on 64bit platforms and 5 on 32bit platforms should
 | 
						|
 * provide a decent safety margin.
 | 
						|
 */
 | 
						|
#ifndef Py_HASH_CUTOFF
 | 
						|
#  define Py_HASH_CUTOFF 0
 | 
						|
#elif (Py_HASH_CUTOFF > 7 || Py_HASH_CUTOFF < 0)
 | 
						|
#  error Py_HASH_CUTOFF must in range 0...7.
 | 
						|
#endif /* Py_HASH_CUTOFF */
 | 
						|
 | 
						|
 | 
						|
/* hash algorithm selection
 | 
						|
 *
 | 
						|
 * The values for Py_HASH_SIPHASH24 and Py_HASH_FNV are hard-coded in the
 | 
						|
 * configure script.
 | 
						|
 *
 | 
						|
 * - FNV is available on all platforms and architectures.
 | 
						|
 * - SIPHASH24 only works on platforms that don't require aligned memory for integers.
 | 
						|
 * - With EXTERNAL embedders can provide an alternative implementation with::
 | 
						|
 *
 | 
						|
 *     PyHash_FuncDef PyHash_Func = {...};
 | 
						|
 *
 | 
						|
 * XXX: Figure out __declspec() for extern PyHash_FuncDef.
 | 
						|
 */
 | 
						|
#define Py_HASH_EXTERNAL 0
 | 
						|
#define Py_HASH_SIPHASH24 1
 | 
						|
#define Py_HASH_FNV 2
 | 
						|
 | 
						|
#ifndef Py_HASH_ALGORITHM
 | 
						|
#  ifndef HAVE_ALIGNED_REQUIRED
 | 
						|
#    define Py_HASH_ALGORITHM Py_HASH_SIPHASH24
 | 
						|
#  else
 | 
						|
#    define Py_HASH_ALGORITHM Py_HASH_FNV
 | 
						|
#  endif /* uint64_t && uint32_t && aligned */
 | 
						|
#endif /* Py_HASH_ALGORITHM */
 | 
						|
 | 
						|
#ifdef __cplusplus
 | 
						|
}
 | 
						|
#endif
 | 
						|
 | 
						|
#endif /* !Py_HASH_H */
 |