/hash-table.c (2df4f0b49d9c139852619af6380646847bcfaf90) (4233 bytes) (mode 100644) (type blob)
#ifndef CGPERF_HASH_TABLE_C
#define CGPERF_HASH_TABLE_C
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "c_fixing.h"
#include "keyword.h"
#include "hash-table.h"
#include "hash.h"
/*------------------------------------------------------------------------------------------------*/
#include "namespace/hash-table.h"
#include "namespace/keyword.h"
#include "namespace/hash.h"
/*------------------------------------------------------------------------------------------------*/
/*{{{ ht_new */
/*
* We make the size of the hash table a power of 2. This allows for two optimizations: It eliminates
* the modulo instruction, and allows for an easy secondary hashing function.
*/
static struct Hash_Table *ht_new(u32 size, bool ignore_length)
{
struct Hash_Table *t;
u32 shift;
t = calloc(1, sizeof(*t));
t->ignore_length = ignore_length;
/* there need to be enough spare entries */
size = size * (u32)ht_size_factor;
/* find smallest power of 2 that is >= size */
shift = 0;
if ((size >> 16) > 0) {
size = size >> 16;
shift += 16;
}
if ((size >> 8) > 0) {
size = size >> 8;
shift += 8;
}
if ((size >> 4) > 0) {
size = size >> 4;
shift += 4;
}
if ((size >> 2) > 0) {
size = size >> 2;
shift += 2;
}
if ((size >> 1) > 0) {
size = size >> 1;
shift += 1;
}
t->log_size = shift;
t->size = 1 << shift;
t->table = calloc(t->size, sizeof(*(t->table)));
return t;
}/*}}}*/
/*{{{ ht_del */
static void ht_del(struct Hash_Table *t)
{
free(t->table);
free(t);
}/*}}}*/
/*{{{ ht_insert */
/*
* Attempts to insert ITEM in the table. If there is already an equal entry in it, returns it.
* Otherwise inserts ITEM and returns NULL.
*/
static struct Keyword *ht_insert(struct Hash_Table *t, struct Keyword *item)
{
u32 hash_val;
u32 probe;
u32 increment;
hash_val = hashpjw((u8*)item->selchars, item->selchars_length * sizeof(u32));
probe = hash_val & (t->size - 1);
increment = (((hash_val >> t->log_size) ^ (t->ignore_length ? 0 : item->allchars_length))
<< 1) + 1;
/*
* note that because _size is a power of 2 and increment is odd, we have
* gcd(increment,_size) = 1, which guarantees that we'll find an empty entry during the loop
*/
loop {
if (t->table[probe] == 0)
break;
if (ht_equal(t, t->table[probe], item))
return t->table[probe];
++(t->collisions);
probe = (probe + increment) & (t->size - 1);
}
t->table[probe] = item;
return 0;
}/*}}}*/
/*{{{ ht_equal */
static bool ht_equal(struct Hash_Table *t, struct Keyword *item1, struct Keyword *item2)
{
return item1->selchars_length == item2->selchars_length
&& memcmp(item1->selchars, item2->selchars, item1->selchars_length * sizeof(u32))
== 0
&& (t->ignore_length || item1->allchars_length == item2->allchars_length);
}/*}}}*/
/*{{{ ht_dump */
static void ht_dump(struct Hash_Table *t)
{
s32 field_width;
s32 i;
field_width = 0;
{
s32 i;
i = t->size - 1;
loop {
if (i < 0)
break;
if (t->table[i] != 0)
if (field_width < t->table[i]->selchars_length)
field_width = t->table[i]->selchars_length;
i--;
}
}
fprintf(stderr, "\ndumping the hash table\ntotal available table slots = %d, total bytes = %d, total collisions = %d\nlocation, %*s, keyword\n", t->size, t->size * (u32)(sizeof(*(t->table))), t->collisions, field_width, "keysig");
i = t->size - 1;
loop {
if (i < 0)
break;
if (t->table[i] != 0) {
s32 j;
fprintf(stderr, "%8d, ", i);
if (field_width > t->table[i]->selchars_length)
fprintf(stderr, "%*s", field_width - t->table[i]->selchars_length, "");
j = 0;
loop {
if (j >= t->table[i]->selchars_length)
break;
putc(t->table[i]->selchars[j], stderr);
++j;
}
fprintf(stderr, ", %.*s\n", t->table[i]->allchars_length, t->table[i]->allchars);
}
i--;
}
fprintf(stderr, "\nend dumping hash table\n\n");
}/*}}}*/
/*------------------------------------------------------------------------------------------------*/
#define EPILOG
#include "namespace/hash-table.h"
#include "namespace/keyword.h"
#include "namespace/hash.h"
#undef EPILOG
/*------------------------------------------------------------------------------------------------*/
#endif
Mode |
Type |
Size |
Ref |
File |
100644 |
blob |
155 |
5b72180098c039db31d1ae3f9cfa9b58038c39e5 |
ABBREVIATIONS |
100644 |
blob |
252 |
82ea1f80bd08bdd20ebf6ff339ac4c1e6963cf54 |
CODING_STYLE |
100644 |
blob |
988 |
84b1a929903fafdfa1b89637d27f1be78091b254 |
README |
100644 |
blob |
255 |
77a9cbb244b51c8ea7271d40680e140fb61d677b |
all.c |
100644 |
blob |
2469 |
88f3c5a85178081ba8ed82cbe444e70364e8f9ac |
bool-array.c |
100644 |
blob |
1301 |
95585899ef9fa01219bb820a0fdb5bf3730d29dc |
bool-array.h |
100644 |
blob |
322 |
a581cb0d698cf4fad768d2e1d76eba8cd95ba620 |
c_fixing.h |
100644 |
blob |
2830 |
cae84c9e018be62e402986d84220972bc44faeda |
getline.c |
100644 |
blob |
803 |
3b2e9fe0fa2789429259320710193649abd8ca6c |
getline.h |
100644 |
blob |
587 |
0e9eb2b35a227500f1457e9ea4c4c0a2765f69e8 |
globals.h |
100644 |
blob |
131227 |
0b67e08b78e02b65a5b85ab33ed9d411ef89b0b0 |
gperf.pdf |
100644 |
blob |
4233 |
2df4f0b49d9c139852619af6380646847bcfaf90 |
hash-table.c |
100644 |
blob |
1637 |
1fb95e378dd619343f3b567687f63d506b8c13bc |
hash-table.h |
100644 |
blob |
980 |
74114adae41af5c48ce02167a9b408a6f1d7d1a0 |
hash.c |
100644 |
blob |
603 |
add7a1a544500039e13f99a1991e0b8a520dc7e5 |
hash.h |
100644 |
blob |
26629 |
a6784a05e9fce47bb13e9e80edcbed10cde77887 |
input.c |
100644 |
blob |
1785 |
1e14807e92c19ea7c276f137e13ac43a887142b4 |
input.h |
100644 |
blob |
4420 |
d7caf4e40dfebcc70161aaa8726586fb03e37ad9 |
keyword.c |
100644 |
blob |
2859 |
b4cbb4e55cbb4b30581207239cdb60deb29e3bed |
keyword.h |
100644 |
blob |
3200 |
d636828dba2bc4ff3c5648900fb7ef8abf7f1f7e |
keyword_list.c |
100644 |
blob |
1493 |
8ab44833fa65bd37719bf3bd6ba994e3325bb7de |
keyword_list.h |
100644 |
blob |
3490 |
a61204584054c59319978812df6869053e98e0f6 |
main.c |
040000 |
tree |
- |
2601d6e758839cb006901fccd9ef537fce13fa3a |
namespace |
100644 |
blob |
35946 |
1fb9da336b25695c248aacf3fb0079febf132bd0 |
options.c |
100644 |
blob |
6711 |
b7853ef0ce8248e2c4cd5a6349ab586201d56368 |
options.h |
100644 |
blob |
57175 |
ce761176a0e5830285d4ef3a585a01816daa579b |
output.c |
100644 |
blob |
4046 |
f0221f3f84539c2fec2f5f68df98f094c145a46e |
output.h |
100644 |
blob |
7272 |
84b2564a5a66f586f89d14e6ff09859161f24f3c |
positions.c |
100644 |
blob |
3699 |
7e1698c33ca484879b5a3454c8d9001d5cdaaaa9 |
positions.h |
100644 |
blob |
55266 |
294deac764f48ec12c61f9c5fa25d50b5863011b |
search.c |
100644 |
blob |
4728 |
2356686527da4e82877472c2b3d75d16f21dec72 |
search.h |
040000 |
tree |
- |
7e446953294cddd2cc0ff66ec0cd1b1654b4c85c |
tests |
100644 |
blob |
99 |
e4da099bacd7a88eeb2db964715d6574fc7fa81e |
version.h |
Hints:
Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"
Clone this repository using HTTP(S):
git clone https://rocketgit.com/user/sylware/cgperf
Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@ssh.rocketgit.com/user/sylware/cgperf
Clone this repository using git:
git clone git://git.rocketgit.com/user/sylware/cgperf
You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a
merge request:
... clone the repository ...
... make some changes and some commits ...
git push origin main