Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-11-19 09:50:49

0001 #ifndef Py_INTERNAL_PYHASH_H
0002 #define Py_INTERNAL_PYHASH_H
0003 
0004 #ifndef Py_BUILD_CORE
0005 #  error "this header requires Py_BUILD_CORE define"
0006 #endif
0007 
0008 // Similar to Py_HashPointer(), but don't replace -1 with -2.
0009 static inline Py_hash_t
0010 _Py_HashPointerRaw(const void *ptr)
0011 {
0012     uintptr_t x = (uintptr_t)ptr;
0013     Py_BUILD_ASSERT(sizeof(x) == sizeof(ptr));
0014 
0015     // Bottom 3 or 4 bits are likely to be 0; rotate x by 4 to the right
0016     // to avoid excessive hash collisions for dicts and sets.
0017     x = (x >> 4) | (x << (8 * sizeof(uintptr_t) - 4));
0018 
0019     Py_BUILD_ASSERT(sizeof(x) == sizeof(Py_hash_t));
0020     return (Py_hash_t)x;
0021 }
0022 
0023 // Export for '_datetime' shared extension
0024 PyAPI_FUNC(Py_hash_t) _Py_HashBytes(const void*, Py_ssize_t);
0025 
0026 /* Hash secret
0027  *
0028  * memory layout on 64 bit systems
0029  *   cccccccc cccccccc cccccccc  uc -- unsigned char[24]
0030  *   pppppppp ssssssss ........  fnv -- two Py_hash_t
0031  *   k0k0k0k0 k1k1k1k1 ........  siphash -- two uint64_t
0032  *   ........ ........ ssssssss  djbx33a -- 16 bytes padding + one Py_hash_t
0033  *   ........ ........ eeeeeeee  pyexpat XML hash salt
0034  *
0035  * memory layout on 32 bit systems
0036  *   cccccccc cccccccc cccccccc  uc
0037  *   ppppssss ........ ........  fnv -- two Py_hash_t
0038  *   k0k0k0k0 k1k1k1k1 ........  siphash -- two uint64_t (*)
0039  *   ........ ........ ssss....  djbx33a -- 16 bytes padding + one Py_hash_t
0040  *   ........ ........ eeee....  pyexpat XML hash salt
0041  *
0042  * (*) The siphash member may not be available on 32 bit platforms without
0043  *     an unsigned int64 data type.
0044  */
0045 typedef union {
0046     /* ensure 24 bytes */
0047     unsigned char uc[24];
0048     /* two Py_hash_t for FNV */
0049     struct {
0050         Py_hash_t prefix;
0051         Py_hash_t suffix;
0052     } fnv;
0053     /* two uint64 for SipHash24 */
0054     struct {
0055         uint64_t k0;
0056         uint64_t k1;
0057     } siphash;
0058     /* a different (!) Py_hash_t for small string optimization */
0059     struct {
0060         unsigned char padding[16];
0061         Py_hash_t suffix;
0062     } djbx33a;
0063     struct {
0064         unsigned char padding[16];
0065         Py_hash_t hashsalt;
0066     } expat;
0067 } _Py_HashSecret_t;
0068 
0069 // Export for '_elementtree' shared extension
0070 PyAPI_DATA(_Py_HashSecret_t) _Py_HashSecret;
0071 
0072 #ifdef Py_DEBUG
0073 extern int _Py_HashSecret_Initialized;
0074 #endif
0075 
0076 
0077 struct pyhash_runtime_state {
0078     struct {
0079 #ifndef MS_WINDOWS
0080         int fd;
0081         dev_t st_dev;
0082         ino_t st_ino;
0083 #else
0084     // This is a placeholder so the struct isn't empty on Windows.
0085     int _not_used;
0086 #endif
0087     } urandom_cache;
0088 };
0089 
0090 #ifndef MS_WINDOWS
0091 # define _py_urandom_cache_INIT \
0092     { \
0093         .fd = -1, \
0094     }
0095 #else
0096 # define _py_urandom_cache_INIT {0}
0097 #endif
0098 
0099 #define pyhash_state_INIT \
0100     { \
0101         .urandom_cache = _py_urandom_cache_INIT, \
0102     }
0103 
0104 
0105 extern uint64_t _Py_KeyedHash(uint64_t key, const void *src, Py_ssize_t src_sz);
0106 
0107 #endif  // !Py_INTERNAL_PYHASH_H