Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(296)

Side by Side Diff: third_party/sqlite/sqlite-src-3080704/src/hash.c

Issue 883353008: [sql] Import reference version of SQLite 3.8.7.4. (Closed) Base URL: http://chromium.googlesource.com/chromium/src.git@master
Patch Set: Hold back encoding change which is messing up patch. Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 ** 2001 September 22 2 ** 2001 September 22
3 ** 3 **
4 ** The author disclaims copyright to this source code. In place of 4 ** The author disclaims copyright to this source code. In place of
5 ** a legal notice, here is a blessing: 5 ** a legal notice, here is a blessing:
6 ** 6 **
7 ** May you do good and not evil. 7 ** May you do good and not evil.
8 ** May you find forgiveness for yourself and forgive others. 8 ** May you find forgiveness for yourself and forgive others.
9 ** May you share freely, never taking more than you give. 9 ** May you share freely, never taking more than you give.
10 ** 10 **
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
45 HashElem *next_elem = elem->next; 45 HashElem *next_elem = elem->next;
46 sqlite3_free(elem); 46 sqlite3_free(elem);
47 elem = next_elem; 47 elem = next_elem;
48 } 48 }
49 pH->count = 0; 49 pH->count = 0;
50 } 50 }
51 51
52 /* 52 /*
53 ** The hashing function. 53 ** The hashing function.
54 */ 54 */
55 static unsigned int strHash(const char *z, int nKey){ 55 static unsigned int strHash(const char *z){
56 int h = 0; 56 unsigned int h = 0;
57 assert( nKey>=0 ); 57 unsigned char c;
58 while( nKey > 0 ){ 58 while( (c = (unsigned char)*z++)!=0 ){
59 h = (h<<3) ^ h ^ sqlite3UpperToLower[(unsigned char)*z++]; 59 h = (h<<3) ^ h ^ sqlite3UpperToLower[c];
60 nKey--;
61 } 60 }
62 return h; 61 return h;
63 } 62 }
64 63
65 64
66 /* Link pNew element into the hash table pH. If pEntry!=0 then also 65 /* Link pNew element into the hash table pH. If pEntry!=0 then also
67 ** insert pNew into the pEntry hash bucket. 66 ** insert pNew into the pEntry hash bucket.
68 */ 67 */
69 static void insertElement( 68 static void insertElement(
70 Hash *pH, /* The complete hash table */ 69 Hash *pH, /* The complete hash table */
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
106 105
107 #if SQLITE_MALLOC_SOFT_LIMIT>0 106 #if SQLITE_MALLOC_SOFT_LIMIT>0
108 if( new_size*sizeof(struct _ht)>SQLITE_MALLOC_SOFT_LIMIT ){ 107 if( new_size*sizeof(struct _ht)>SQLITE_MALLOC_SOFT_LIMIT ){
109 new_size = SQLITE_MALLOC_SOFT_LIMIT/sizeof(struct _ht); 108 new_size = SQLITE_MALLOC_SOFT_LIMIT/sizeof(struct _ht);
110 } 109 }
111 if( new_size==pH->htsize ) return 0; 110 if( new_size==pH->htsize ) return 0;
112 #endif 111 #endif
113 112
114 /* The inability to allocates space for a larger hash table is 113 /* The inability to allocates space for a larger hash table is
115 ** a performance hit but it is not a fatal error. So mark the 114 ** a performance hit but it is not a fatal error. So mark the
116 ** allocation as a benign. 115 ** allocation as a benign. Use sqlite3Malloc()/memset(0) instead of
116 ** sqlite3MallocZero() to make the allocation, as sqlite3MallocZero()
117 ** only zeroes the requested number of bytes whereas this module will
118 ** use the actual amount of space allocated for the hash table (which
119 ** may be larger than the requested amount).
117 */ 120 */
118 sqlite3BeginBenignMalloc(); 121 sqlite3BeginBenignMalloc();
119 new_ht = (struct _ht *)sqlite3Malloc( new_size*sizeof(struct _ht) ); 122 new_ht = (struct _ht *)sqlite3Malloc( new_size*sizeof(struct _ht) );
120 sqlite3EndBenignMalloc(); 123 sqlite3EndBenignMalloc();
121 124
122 if( new_ht==0 ) return 0; 125 if( new_ht==0 ) return 0;
123 sqlite3_free(pH->ht); 126 sqlite3_free(pH->ht);
124 pH->ht = new_ht; 127 pH->ht = new_ht;
125 pH->htsize = new_size = sqlite3MallocSize(new_ht)/sizeof(struct _ht); 128 pH->htsize = new_size = sqlite3MallocSize(new_ht)/sizeof(struct _ht);
126 memset(new_ht, 0, new_size*sizeof(struct _ht)); 129 memset(new_ht, 0, new_size*sizeof(struct _ht));
127 for(elem=pH->first, pH->first=0; elem; elem = next_elem){ 130 for(elem=pH->first, pH->first=0; elem; elem = next_elem){
128 unsigned int h = strHash(elem->pKey, elem->nKey) % new_size; 131 unsigned int h = strHash(elem->pKey) % new_size;
129 next_elem = elem->next; 132 next_elem = elem->next;
130 insertElement(pH, &new_ht[h], elem); 133 insertElement(pH, &new_ht[h], elem);
131 } 134 }
132 return 1; 135 return 1;
133 } 136 }
134 137
135 /* This function (for internal use only) locates an element in an 138 /* This function (for internal use only) locates an element in an
136 ** hash table that matches the given key. The hash for this key has 139 ** hash table that matches the given key. The hash for this key is
137 ** already been computed and is passed as the 4th parameter. 140 ** also computed and returned in the *pH parameter.
138 */ 141 */
139 static HashElem *findElementGivenHash( 142 static HashElem *findElementWithHash(
140 const Hash *pH, /* The pH to be searched */ 143 const Hash *pH, /* The pH to be searched */
141 const char *pKey, /* The key we are searching for */ 144 const char *pKey, /* The key we are searching for */
142 int nKey, /* Bytes in key (not counting zero terminator) */ 145 unsigned int *pHash /* Write the hash value here */
143 unsigned int h /* The hash for this key. */
144 ){ 146 ){
145 HashElem *elem; /* Used to loop thru the element list */ 147 HashElem *elem; /* Used to loop thru the element list */
146 int count; /* Number of elements left to test */ 148 int count; /* Number of elements left to test */
149 unsigned int h; /* The computed hash */
147 150
148 if( pH->ht ){ 151 if( pH->ht ){
149 struct _ht *pEntry = &pH->ht[h]; 152 struct _ht *pEntry;
153 h = strHash(pKey) % pH->htsize;
154 pEntry = &pH->ht[h];
150 elem = pEntry->chain; 155 elem = pEntry->chain;
151 count = pEntry->count; 156 count = pEntry->count;
152 }else{ 157 }else{
158 h = 0;
153 elem = pH->first; 159 elem = pH->first;
154 count = pH->count; 160 count = pH->count;
155 } 161 }
156 while( count-- && ALWAYS(elem) ){ 162 *pHash = h;
157 if( elem->nKey==nKey && sqlite3StrNICmp(elem->pKey,pKey,nKey)==0 ){ 163 while( count-- ){
164 assert( elem!=0 );
165 if( sqlite3StrICmp(elem->pKey,pKey)==0 ){
158 return elem; 166 return elem;
159 } 167 }
160 elem = elem->next; 168 elem = elem->next;
161 } 169 }
162 return 0; 170 return 0;
163 } 171 }
164 172
165 /* Remove a single entry from the hash table given a pointer to that 173 /* Remove a single entry from the hash table given a pointer to that
166 ** element and a hash on the element's key. 174 ** element and a hash on the element's key.
167 */ 175 */
(...skipping 14 matching lines...) Expand all
182 if( pH->ht ){ 190 if( pH->ht ){
183 pEntry = &pH->ht[h]; 191 pEntry = &pH->ht[h];
184 if( pEntry->chain==elem ){ 192 if( pEntry->chain==elem ){
185 pEntry->chain = elem->next; 193 pEntry->chain = elem->next;
186 } 194 }
187 pEntry->count--; 195 pEntry->count--;
188 assert( pEntry->count>=0 ); 196 assert( pEntry->count>=0 );
189 } 197 }
190 sqlite3_free( elem ); 198 sqlite3_free( elem );
191 pH->count--; 199 pH->count--;
192 if( pH->count<=0 ){ 200 if( pH->count==0 ){
193 assert( pH->first==0 ); 201 assert( pH->first==0 );
194 assert( pH->count==0 ); 202 assert( pH->count==0 );
195 sqlite3HashClear(pH); 203 sqlite3HashClear(pH);
196 } 204 }
197 } 205 }
198 206
199 /* Attempt to locate an element of the hash table pH with a key 207 /* Attempt to locate an element of the hash table pH with a key
200 ** that matches pKey,nKey. Return the data for this element if it is 208 ** that matches pKey. Return the data for this element if it is
201 ** found, or NULL if there is no match. 209 ** found, or NULL if there is no match.
202 */ 210 */
203 void *sqlite3HashFind(const Hash *pH, const char *pKey, int nKey){ 211 void *sqlite3HashFind(const Hash *pH, const char *pKey){
204 HashElem *elem; /* The element that matches key */ 212 HashElem *elem; /* The element that matches key */
205 unsigned int h; /* A hash on key */ 213 unsigned int h; /* A hash on key */
206 214
207 assert( pH!=0 ); 215 assert( pH!=0 );
208 assert( pKey!=0 ); 216 assert( pKey!=0 );
209 assert( nKey>=0 ); 217 elem = findElementWithHash(pH, pKey, &h);
210 if( pH->ht ){
211 h = strHash(pKey, nKey) % pH->htsize;
212 }else{
213 h = 0;
214 }
215 elem = findElementGivenHash(pH, pKey, nKey, h);
216 return elem ? elem->data : 0; 218 return elem ? elem->data : 0;
217 } 219 }
218 220
219 /* Insert an element into the hash table pH. The key is pKey,nKey 221 /* Insert an element into the hash table pH. The key is pKey
220 ** and the data is "data". 222 ** and the data is "data".
221 ** 223 **
222 ** If no element exists with a matching key, then a new 224 ** If no element exists with a matching key, then a new
223 ** element is created and NULL is returned. 225 ** element is created and NULL is returned.
224 ** 226 **
225 ** If another element already exists with the same key, then the 227 ** If another element already exists with the same key, then the
226 ** new data replaces the old data and the old data is returned. 228 ** new data replaces the old data and the old data is returned.
227 ** The key is not copied in this instance. If a malloc fails, then 229 ** The key is not copied in this instance. If a malloc fails, then
228 ** the new data is returned and the hash table is unchanged. 230 ** the new data is returned and the hash table is unchanged.
229 ** 231 **
230 ** If the "data" parameter to this function is NULL, then the 232 ** If the "data" parameter to this function is NULL, then the
231 ** element corresponding to "key" is removed from the hash table. 233 ** element corresponding to "key" is removed from the hash table.
232 */ 234 */
233 void *sqlite3HashInsert(Hash *pH, const char *pKey, int nKey, void *data){ 235 void *sqlite3HashInsert(Hash *pH, const char *pKey, void *data){
234 unsigned int h; /* the hash of the key modulo hash table size */ 236 unsigned int h; /* the hash of the key modulo hash table size */
235 HashElem *elem; /* Used to loop thru the element list */ 237 HashElem *elem; /* Used to loop thru the element list */
236 HashElem *new_elem; /* New element added to the pH */ 238 HashElem *new_elem; /* New element added to the pH */
237 239
238 assert( pH!=0 ); 240 assert( pH!=0 );
239 assert( pKey!=0 ); 241 assert( pKey!=0 );
240 assert( nKey>=0 ); 242 elem = findElementWithHash(pH,pKey,&h);
241 if( pH->htsize ){
242 h = strHash(pKey, nKey) % pH->htsize;
243 }else{
244 h = 0;
245 }
246 elem = findElementGivenHash(pH,pKey,nKey,h);
247 if( elem ){ 243 if( elem ){
248 void *old_data = elem->data; 244 void *old_data = elem->data;
249 if( data==0 ){ 245 if( data==0 ){
250 removeElementGivenHash(pH,elem,h); 246 removeElementGivenHash(pH,elem,h);
251 }else{ 247 }else{
252 elem->data = data; 248 elem->data = data;
253 elem->pKey = pKey; 249 elem->pKey = pKey;
254 assert(nKey==elem->nKey);
255 } 250 }
256 return old_data; 251 return old_data;
257 } 252 }
258 if( data==0 ) return 0; 253 if( data==0 ) return 0;
259 new_elem = (HashElem*)sqlite3Malloc( sizeof(HashElem) ); 254 new_elem = (HashElem*)sqlite3Malloc( sizeof(HashElem) );
260 if( new_elem==0 ) return data; 255 if( new_elem==0 ) return data;
261 new_elem->pKey = pKey; 256 new_elem->pKey = pKey;
262 new_elem->nKey = nKey;
263 new_elem->data = data; 257 new_elem->data = data;
264 pH->count++; 258 pH->count++;
265 if( pH->count>=10 && pH->count > 2*pH->htsize ){ 259 if( pH->count>=10 && pH->count > 2*pH->htsize ){
266 if( rehash(pH, pH->count*2) ){ 260 if( rehash(pH, pH->count*2) ){
267 assert( pH->htsize>0 ); 261 assert( pH->htsize>0 );
268 h = strHash(pKey, nKey) % pH->htsize; 262 h = strHash(pKey) % pH->htsize;
269 } 263 }
270 } 264 }
271 if( pH->ht ){ 265 insertElement(pH, pH->ht ? &pH->ht[h] : 0, new_elem);
272 insertElement(pH, &pH->ht[h], new_elem);
273 }else{
274 insertElement(pH, 0, new_elem);
275 }
276 return 0; 266 return 0;
277 } 267 }
OLDNEW
« no previous file with comments | « third_party/sqlite/sqlite-src-3080704/src/hash.h ('k') | third_party/sqlite/sqlite-src-3080704/src/hwtime.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698