2 This file is part of the software library CADLIB written by Conrad Ziesler
3 Copyright 2003, Conrad Ziesler, all rights reserved.
5 *************************
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 /* hash.c : Hash table functions for string identifier lookup
31 unsigned int hash_strhash(int max
, void *data
, int size
)
40 r
+=((unsigned int)(str
[0]&0x7f));
51 #define quickhashbin(a,b,c) hash_binhash(a,b,c)
53 unsigned int hash_binhash(int max
, void *data
, int size
)
61 r
+=((unsigned int)(str
[0]&0x7f));
71 static hashbin_t
*hash_newbin(void *copyfrom
, int size
)
75 p
=malloc(size
+sizeof(hashbin_t
));
80 memcpy(hash_bin2user(p
),copyfrom
,size
);
85 static hashbin_t
*hash_insert(hash_t
*h
, unsigned int index
, hashbin_t
*cp
)
87 cp
->next
=h
->bins
[index
];
93 static hashbin_t
*hash_insertsorted(hash_t
*h
, hashbin_t
*head
, hashbin_t
*cp
)
97 for(a
=head
;a
!=NULL
;a
=a
->next
)
99 if(h
->hashcmp(a
,cp
)>=0)
129 static hashbin_t
*hash_findbin(hash_t
*h
, hashbin_t
*start
, int ksize
, void *key
)
133 if(h
->hashcmp(ksize
,key
,start
->size
,start
+1)==0)return start
;
141 /******* public functions ********/
142 void hash_free (hash_t
*h
)
149 for(i
=0;i
<h
->qalloc
;i
++)
150 if(h
->alloc
[i
]!=NULL
)free(h
->alloc
[i
]);
151 for(i
=0;i
<h
->qbin
;i
++)
153 for(p
=h
->bins
[i
];p
!=NULL
;p
=np
)
166 uint (*hashfunc
)(int max
, void *data
, int size
),
167 int (*hashcmp
)(int sizea
, void *a
, int sizeb
, void *b
)
173 p
=malloc(sizeof(hash_t
)+(sizeof(hashbin_t
*)*qbins
) );
175 p
->bins
=(void *) (((char *)p
)+sizeof(hash_t
));
178 p
->hashfunc
=hashfunc
;
188 void *hash_find(hash_t
*h
, void *key
, int ksize
)
194 ukey
=h
->hashfunc(h
->qbin
,key
,ksize
);
195 assert(ukey
<h
->qbin
);
197 fbin
=hash_findbin(h
,h
->bins
[ukey
],ksize
,key
);
199 if(fbin
==NULL
)return NULL
;
200 return hash_bin2user(fbin
);
203 int hash_size(void *user
)
206 if(user
==NULL
)return 0;
207 bin
=hash_user2bin(user
);
211 void *hash_add(hash_t
*h
, void *key
, int ksize
)
214 hashbin_t
*fbin
, *dbin
;
218 ukey
=h
->hashfunc(h
->qbin
,key
,ksize
);
219 assert(ukey
<h
->qbin
);
221 fbin
=hash_findbin(h
,h
->bins
[ukey
],ksize
,key
);
224 dbin
=hash_newbin(key
,ksize
);
225 fbin
=hash_insert(h
,ukey
,dbin
);
228 return hash_bin2user(fbin
);
233 uint
hclient_ptrflagstr_hash(int max
, void *data
, int size
)
235 return hash_strhash(max
, ((char *)data
) + sizeof(hclient_ptrflagstr_t
) ,size
-sizeof(hclient_ptrflagstr_t
));
238 int hclient_ptrflagstr_cmp(hashbin_t
*a
, hashbin_t
*b
)
241 if(b
==NULL
)return -1;
242 if(a
->size
> b
->size
) return 1;
243 if(a
->size
< b
->size
) return -1;
244 return strcmp( ((char *) hash_bin2user(a
) ) + sizeof(hclient_ptrflagstr_t
), ((char *) hash_bin2user(b
) ) + sizeof(hclient_ptrflagstr_t
) );
250 straight binary comparison and hash
253 uint
hclient_bobject_hash(int max
, void *data
, int size
)
255 return quickhashbin(max
,data
,size
);
258 int hclient_bobject_cmp(int sizea
, void *a
, int sizeb
, void *b
)
261 if(b
==NULL
)return -1;
262 if(sizea
> sizeb
) return 1;
263 if(sizea
< sizeb
) return -1;
264 return memcmp(a
,b
,sizea
);