@@ -106,13 +106,34 @@ static void entry_reclaim (hentry* entry,
106106 entry = entry_destroy (entry , keyfreefn , valfreefn );
107107}
108108
109- static void * entry_find (hentry * entry , const void * const key , hashTableEqualFunc equalfn ,
109+ /* Looking for an entry having KEY as its key in the chain:
110+ * entry, entry->next, entry->next->next,...
111+ *
112+ * We have a chance to optimize for the case when a same key is
113+ * used repeatedly. By moving the entry found in the last time to
114+ * the head of the chain, we can avoid taking time for tracking
115+ * down the ->next-> chain.
116+ * The cost for the optimization is very small.
117+ */
118+ static void * entry_find (hentry * * root_entry , const void * const key , hashTableEqualFunc equalfn ,
110119 void * valForNotUnknownKey )
111120{
121+ hentry * entry = * root_entry ;
122+ hentry * last = NULL ;
112123 while (entry )
113124 {
114125 if (equalfn ( key , entry -> key ))
126+ {
127+ if (last )
128+ {
129+ last -> next = entry -> next ;
130+ entry -> next = * root_entry ;
131+ * root_entry = entry ;
132+ }
115133 return entry -> value ;
134+ }
135+
136+ last = entry ;
116137 entry = entry -> next ;
117138 }
118139 return valForNotUnknownKey ;
@@ -308,7 +329,7 @@ extern void* hashTableGetItem (hashTable *htable, const void * key)
308329
309330 h = htable -> hashfn (key );
310331 i = h % htable -> size ;
311- return entry_find (htable -> table [i ], key , htable -> equalfn , htable -> valForNotUnknownKey );
332+ return entry_find (& ( htable -> table [i ]) , key , htable -> equalfn , htable -> valForNotUnknownKey );
312333}
313334
314335extern bool hashTableDeleteItem (hashTable * htable , const void * key )
0 commit comments