Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-26 09:15:11

0001 // Protocol Buffers - Google's data interchange format
0002 // Copyright 2023 Google LLC.  All rights reserved.
0003 //
0004 // Use of this source code is governed by a BSD-style
0005 // license that can be found in the LICENSE file or at
0006 // https://developers.google.com/open-source/licenses/bsd
0007 
0008 /*
0009  * upb_table
0010  *
0011  * This header is INTERNAL-ONLY!  Its interfaces are not public or stable!
0012  * This file defines very fast int->upb_value (inttable) and string->upb_value
0013  * (strtable) hash tables.
0014  *
0015  * The table uses chained scatter with Brent's variation (inspired by the Lua
0016  * implementation of hash tables).  The hash function for strings is Austin
0017  * Appleby's "MurmurHash."
0018  *
0019  * The inttable uses uintptr_t as its key, which guarantees it can be used to
0020  * store pointers or integers of at least 32 bits (upb isn't really useful on
0021  * systems where sizeof(void*) < 4).
0022  *
0023  * The table must be homogeneous (all values of the same type).  In debug
0024  * mode, we check this on insert and lookup.
0025  */
0026 
0027 #ifndef UPB_HASH_COMMON_H_
0028 #define UPB_HASH_COMMON_H_
0029 
0030 #include <stdint.h>
0031 #include <string.h>
0032 
0033 #include "upb/base/string_view.h"
0034 
0035 // Must be last.
0036 #include "upb/port/def.inc"
0037 
0038 #ifdef __cplusplus
0039 extern "C" {
0040 #endif
0041 
0042 /* upb_value ******************************************************************/
0043 
0044 typedef struct {
0045   uint64_t val;
0046 } upb_value;
0047 
0048 /* For each value ctype, define the following set of functions:
0049  *
0050  * // Get/set an int32 from a upb_value.
0051  * int32_t upb_value_getint32(upb_value val);
0052  * void upb_value_setint32(upb_value *val, int32_t cval);
0053  *
0054  * // Construct a new upb_value from an int32.
0055  * upb_value upb_value_int32(int32_t val); */
0056 #define FUNCS(name, membername, type_t, converter)                   \
0057   UPB_INLINE void upb_value_set##name(upb_value* val, type_t cval) { \
0058     val->val = (uint64_t)cval;                                       \
0059   }                                                                  \
0060   UPB_INLINE upb_value upb_value_##name(type_t val) {                \
0061     upb_value ret;                                                   \
0062     upb_value_set##name(&ret, val);                                  \
0063     return ret;                                                      \
0064   }                                                                  \
0065   UPB_INLINE type_t upb_value_get##name(upb_value val) {             \
0066     return (type_t)(converter)val.val;                               \
0067   }
0068 
0069 FUNCS(int32, int32, int32_t, int32_t)
0070 FUNCS(int64, int64, int64_t, int64_t)
0071 FUNCS(uint32, uint32, uint32_t, uint32_t)
0072 FUNCS(uint64, uint64, uint64_t, uint64_t)
0073 FUNCS(bool, _bool, bool, bool)
0074 FUNCS(cstr, cstr, char*, uintptr_t)
0075 FUNCS(uintptr, uptr, uintptr_t, uintptr_t)
0076 FUNCS(ptr, ptr, void*, uintptr_t)
0077 FUNCS(constptr, constptr, const void*, uintptr_t)
0078 
0079 #undef FUNCS
0080 
0081 UPB_INLINE void upb_value_setfloat(upb_value* val, float cval) {
0082   memcpy(&val->val, &cval, sizeof(cval));
0083 }
0084 
0085 UPB_INLINE void upb_value_setdouble(upb_value* val, double cval) {
0086   memcpy(&val->val, &cval, sizeof(cval));
0087 }
0088 
0089 UPB_INLINE upb_value upb_value_float(float cval) {
0090   upb_value ret;
0091   upb_value_setfloat(&ret, cval);
0092   return ret;
0093 }
0094 
0095 UPB_INLINE upb_value upb_value_double(double cval) {
0096   upb_value ret;
0097   upb_value_setdouble(&ret, cval);
0098   return ret;
0099 }
0100 
0101 /* upb_key *****************************************************************/
0102 
0103 // A uint32 size followed by that number of bytes stored contiguously.
0104 typedef struct {
0105   uint32_t size;
0106   const char data[];
0107 } upb_SizePrefixString;
0108 
0109 /* Either:
0110  *   1. an actual integer key
0111  *   2. a SizePrefixString*, owned by us.
0112  *
0113  * ...depending on whether this is a string table or an int table. */
0114 typedef union {
0115   uintptr_t num;
0116   const upb_SizePrefixString* str;
0117 } upb_key;
0118 
0119 UPB_INLINE upb_StringView upb_key_strview(upb_key key) {
0120   return upb_StringView_FromDataAndSize(key.str->data, key.str->size);
0121 }
0122 
0123 /* upb_table ******************************************************************/
0124 
0125 typedef struct _upb_tabent {
0126   upb_value val;
0127   upb_key key;
0128 
0129   /* Internal chaining.  This is const so we can create static initializers for
0130    * tables.  We cast away const sometimes, but *only* when the containing
0131    * upb_table is known to be non-const.  This requires a bit of care, but
0132    * the subtlety is confined to table.c. */
0133   const struct _upb_tabent* next;
0134 } upb_tabent;
0135 
0136 typedef struct {
0137   upb_tabent* entries;
0138   /* Number of entries in the hash part. */
0139   uint32_t count;
0140 
0141   /* Mask to turn hash value -> bucket. The map's allocated size is mask + 1.*/
0142   uint32_t mask;
0143 } upb_table;
0144 
0145 UPB_INLINE size_t upb_table_size(const upb_table* t) { return t->mask + 1; }
0146 
0147 // Internal-only functions, in .h file only out of necessity.
0148 
0149 UPB_INLINE upb_key upb_key_empty(void) {
0150   upb_key ret;
0151   memset(&ret, 0, sizeof(upb_key));
0152   return ret;
0153 }
0154 
0155 UPB_INLINE bool upb_tabent_isempty(const upb_tabent* e) {
0156   upb_key key = e->key;
0157   UPB_ASSERT(sizeof(key.num) == sizeof(key.str));
0158   uintptr_t val;
0159   memcpy(&val, &key, sizeof(val));
0160   // Note: for upb_inttables a tab_key is a true integer key value, but the
0161   // inttable maintains the invariant that 0 value is always stored in the
0162   // compact table and never as a upb_tabent* so we can always use the 0
0163   // key value to identify an empty tabent.
0164   return val == 0;
0165 }
0166 
0167 uint32_t _upb_Hash(const void* p, size_t n, uint64_t seed);
0168 
0169 #ifdef __cplusplus
0170 } /* extern "C" */
0171 #endif
0172 
0173 #include "upb/port/undef.inc"
0174 
0175 #endif /* UPB_HASH_COMMON_H_ */