-#define DICT_INSERT( zdict, zint, zstring, zdata ) { \
- uint64_t i_hash = DictHash( (zstring), (zint) ); \
- int i_new; \
- /* Find a free slot */ \
- if( zdict->i_entries == 0 || i_hash <= zdict->p_entries[0].i_hash ) \
- i_new = 0; \
- else if( i_hash >= zdict->p_entries[zdict->i_entries-1].i_hash ) \
- i_new = zdict->i_entries;\
- else \
- { \
- int i_low = 0, i_high = zdict->i_entries - 1; \
- while( i_high - i_low > 1 ) \
- { \
- int i_mid = (i_low + i_high)/2; \
- fprintf(stderr, "Low %i, high %i\n", i_low, i_high); \
- if( zdict->p_entries[i_mid].i_hash < i_hash ) { \
- i_low = i_mid; \
- } else if( zdict->p_entries[i_mid].i_hash > i_hash ) { \
- i_high = i_mid; \
- } \
- } \
- if( zdict->p_entries[i_low].i_hash < i_hash ) \
- i_new = i_high; \
- else \
- i_new = i_low; \
- } \
- zdict->p_entries = realloc( zdict->p_entries, (zdict->i_entries + 1) * \
- ( sizeof(zdata) + sizeof(int) + sizeof(void*) + sizeof(uint64_t) ) ); \
- zdict->i_entries++; \
- if( i_new != zdict->i_entries -1 ) \
- memmove( &zdict->p_entries[i_new+1], &zdict->p_entries[i_new], \
- ( zdict->i_entries - i_new - 1 ) * \
- ( sizeof(zdata) + sizeof(int) + sizeof(void*) + sizeof(uint64_t) ) );\
- \
- zdict->p_entries[i_new].i_hash = i_hash; \
- zdict->p_entries[i_new].i_int = (zint); \
- if( (zstring) ) { \
- zdict->p_entries[i_new].psz_string = strdup( (zstring) ); \
- } else { \
- zdict->p_entries[i_new].psz_string = NULL; \
- } \
- zdict->p_entries[i_new].data = zdata; \
+
+static inline void *
+vlc_dictionary_value_for_key( vlc_dictionary_t * p_dict, const char * psz_key )
+{
+ uint64_t i_hash;
+ int i, i_pos;
+
+ if( p_dict->i_entries == 0 )
+ return kVLCDictionaryNotFound;
+
+ i_hash = DictHash( psz_key );
+ BSEARCH( p_dict->p_entries, p_dict->i_entries, .i_hash, uint64_t,
+ i_hash, i_pos );
+ if( i_pos == -1 )
+ return kVLCDictionaryNotFound;
+
+ /* Hash found, let's check it looks like the entry */
+ if( !strcmp( psz_key, p_dict->p_entries[i_pos].psz_key ) )
+ return p_dict->p_entries[i_pos].p_value;
+
+ /* Hash collision! This should be very rare, but we cannot guarantee
+ * it will never happen. Just do an exhaustive search amongst all
+ * entries with the same hash. */
+ for( i = i_pos - 1 ; i > 0 && i_hash == p_dict->p_entries[i].i_hash ; i-- )
+ {
+ if( !strcmp( psz_key, p_dict->p_entries[i].psz_key ) )
+ return p_dict->p_entries[i_pos].p_value;
+ }
+ for( i = i_pos + 1 ; i < p_dict->i_entries &&
+ i_hash == p_dict->p_entries[i].i_hash ; i++ )
+ {
+ if( !strcmp( psz_key, p_dict->p_entries[i].psz_key ))
+ return p_dict->p_entries[i_pos].p_value;
+ }
+ /* Hash found, but entry not found (shouldn't happen!) */
+ return kVLCDictionaryNotFound;