File src/hashmap.c added (mode: 100644) (index 0000000..060751c) |
|
1 |
|
#include "include/hashmap.h" |
|
2 |
|
|
|
3 |
|
unsigned int hashmap_hash( const char *str ) { |
|
4 |
|
int i; |
|
5 |
|
unsigned int result = 0; |
|
6 |
|
|
|
7 |
|
for( i = 0; str[ i ] != '\0'; i++ ) |
|
8 |
|
result = result * 31 + str[ i ]; |
|
9 |
|
|
|
10 |
|
return result % HASH_MAP_SIZE; |
|
11 |
|
} |
|
12 |
|
|
|
13 |
|
void hashmap_init( HashMap * hs ) { |
|
14 |
|
int i; |
|
15 |
|
hs->currentSize = 0; |
|
16 |
|
for( i = 0; i < HASH_MAP_SIZE; i++ ) { |
|
17 |
|
hs->lists[ i ] = NULL; |
|
18 |
|
} |
|
19 |
|
} |
|
20 |
|
|
|
21 |
|
void *hashmap_get( const HashMap * hs, const char *key ) { |
|
22 |
|
int listNum = hashmap_hash( key ); |
|
23 |
|
struct HashMapNode *ptr = hs->lists[ listNum ]; |
|
24 |
|
|
|
25 |
|
while( ptr != NULL && strcmp( ptr->key, key ) != 0 ) |
|
26 |
|
ptr = ptr->next; |
|
27 |
|
|
|
28 |
|
return (ptr != NULL? ptr->value : NULL); |
|
29 |
|
} |
|
30 |
|
|
|
31 |
|
int hashmap_put( HashMap * hs, const char *key, void *value) { |
|
32 |
|
struct HashMapNode *newNode; |
|
33 |
|
int listNum; |
|
34 |
|
|
|
35 |
|
if( hashmap_get( hs, key ) ) |
|
36 |
|
return 0; |
|
37 |
|
|
|
38 |
|
listNum = hashmap_hash( key ); |
|
39 |
|
|
|
40 |
|
|
|
41 |
|
newNode = (struct HashMapNode *) malloc( sizeof ( struct HashMapNode ) ); |
|
42 |
|
if( newNode == NULL ) { |
|
43 |
|
fprintf( stderr, "Error allocating node" ); |
|
44 |
|
return 0; |
|
45 |
|
} |
|
46 |
|
|
|
47 |
|
newNode->key = strdup( key ); |
|
48 |
|
newNode->value = value; |
|
49 |
|
newNode->next = hs->lists[ listNum ]; |
|
50 |
|
hs->lists[ listNum ] = newNode; |
|
51 |
|
hs->currentSize++; |
|
52 |
|
|
|
53 |
|
return 1; |
|
54 |
|
} |
|
55 |
|
|
|
56 |
|
int hashmap_size(const HashMap * hs) { |
|
57 |
|
return hs->currentSize; |
|
58 |
|
} |
|
59 |
|
|
|
60 |
|
void hashmap_print( const HashMap * hs ) { |
|
61 |
|
int i; |
|
62 |
|
struct HashMapNode *ptr; |
|
63 |
|
|
|
64 |
|
for( i = 0; i < HASH_MAP_SIZE; i++ ) |
|
65 |
|
for( ptr = hs->lists[ i ]; ptr != NULL; ptr = ptr->next ) |
|
66 |
|
printf( "%s\n", ptr->key ); |
|
67 |
|
} |
File src/include/hashmap.h added (mode: 100644) (index 0000000..28b9eaa) |
|
1 |
|
#ifndef _HASHMAP_H_ |
|
2 |
|
#define _HASHMAP_H_ |
|
3 |
|
|
|
4 |
|
#include <stdlib.h> |
|
5 |
|
#include <stdio.h> |
|
6 |
|
#include <string.h> |
|
7 |
|
|
|
8 |
|
#define HASH_MAP_SIZE 10007 |
|
9 |
|
|
|
10 |
|
struct HashMapNode { |
|
11 |
|
char *key; |
|
12 |
|
void *value; |
|
13 |
|
struct HashMapNode *next; |
|
14 |
|
}; |
|
15 |
|
|
|
16 |
|
typedef struct { |
|
17 |
|
struct HashMapNode * lists[HASH_MAP_SIZE]; |
|
18 |
|
int currentSize; |
|
19 |
|
} HashMap; |
|
20 |
|
|
|
21 |
|
void hashmap_init( HashMap *hm ); |
|
22 |
|
void *hashmap_get( const HashMap *hm, const char *key ); |
|
23 |
|
int hashmap_put( HashMap *hm, const char *key, void *value ); |
|
24 |
|
int hashmap_size( const HashMap *hm ); |
|
25 |
|
void hashmap_print( const HashMap *hm ); |
|
26 |
|
|
|
27 |
|
#endif /* HASHMAP_H_ */ |
File src/include/radixsort.h added (mode: 100644) (index 0000000..c2a87ae) |
|
1 |
|
#ifndef RADIXSORT_H_ |
|
2 |
|
#define RADIXSORT_H_ |
|
3 |
|
|
|
4 |
|
typedef struct radixitem { |
|
5 |
|
unsigned key; |
|
6 |
|
void *data; |
|
7 |
|
struct radixitem *next; |
|
8 |
|
} RadixItem; |
|
9 |
|
|
|
10 |
|
#define SIX2FOUR_SIZE 1000 |
|
11 |
|
|
|
12 |
|
typedef struct { |
|
13 |
|
unsigned size; |
|
14 |
|
unsigned maxValue; |
|
15 |
|
RadixItem **six2four[SIX2FOUR_SIZE]; |
|
16 |
|
} RadixSorter; |
|
17 |
|
|
|
18 |
|
void radixsort_init(RadixSorter *rs); |
|
19 |
|
void radixsort_add(RadixSorter *rs, RadixItem *item); |
|
20 |
|
RadixItem *radix_cut(RadixSorter *rs, unsigned key, void *data); |
|
21 |
|
RadixItem **radixsort_dump(RadixSorter *rs); |
|
22 |
|
|
|
23 |
|
#endif /* RADIXSORT_H_ */ |
File src/radixsort.c added (mode: 100644) (index 0000000..e64d060) |
|
1 |
|
#include "include/radixsort.h" |
|
2 |
|
#include <stdlib.h> |
|
3 |
|
#include <stdio.h> |
|
4 |
|
#include <math.h> |
|
5 |
|
#include <string.h> |
|
6 |
|
#include <stddef.h> |
|
7 |
|
|
|
8 |
|
RadixItem **radixsort_get_slot() { |
|
9 |
|
RadixItem **slot=malloc(SIX2FOUR_SIZE * sizeof(RadixItem*)); |
|
10 |
|
memset(slot, 0, SIX2FOUR_SIZE * sizeof(RadixItem*)); |
|
11 |
|
return slot; |
|
12 |
|
} |
|
13 |
|
|
|
14 |
|
void radixsort_init(RadixSorter *rs) { |
|
15 |
|
rs->size=0; |
|
16 |
|
memset(rs->six2four, 0, SIX2FOUR_SIZE * sizeof(RadixItem*)); |
|
17 |
|
rs->maxValue=0; |
|
18 |
|
} |
|
19 |
|
|
|
20 |
|
void radixsort_add(RadixSorter *rs, RadixItem *item) { |
|
21 |
|
double d = ((double) item->key)/1000.0; |
|
22 |
|
unsigned six2four = (unsigned)trunc(d); |
|
23 |
|
unsigned three2zero=item->key-six2four*1000; |
|
24 |
|
|
|
25 |
|
if(rs->six2four[six2four]==NULL) { |
|
26 |
|
rs->six2four[six2four]=radixsort_get_slot(); |
|
27 |
|
} |
|
28 |
|
|
|
29 |
|
RadixItem *chain=rs->six2four[six2four][three2zero]; |
|
30 |
|
rs->six2four[six2four][three2zero]=item; |
|
31 |
|
if(chain==NULL) { |
|
32 |
|
item->next=NULL; |
|
33 |
|
} else { |
|
34 |
|
item->next=chain; |
|
35 |
|
} |
|
36 |
|
|
|
37 |
|
rs->size++; |
|
38 |
|
rs->maxValue=(rs->maxValue>item->key?rs->maxValue:item->key); |
|
39 |
|
} |
|
40 |
|
|
|
41 |
|
RadixItem **radixsort_dump(RadixSorter *rs) { |
|
42 |
|
if(rs->size>0) { |
|
43 |
|
RadixItem **result=malloc(rs->size * sizeof(RadixItem *)); |
|
44 |
|
double d = ((double)rs->maxValue)/1000.0; |
|
45 |
|
int six2four = (int)trunc(d); |
|
46 |
|
|
|
47 |
|
int s, t, i=0; |
|
48 |
|
s=six2four; |
|
49 |
|
do { |
|
50 |
|
t=SIX2FOUR_SIZE-1; |
|
51 |
|
do { |
|
52 |
|
if(rs->six2four[s]!=NULL) { |
|
53 |
|
if(rs->six2four[s][t]!=NULL) { |
|
54 |
|
result[i++]=rs->six2four[s][t]; |
|
55 |
|
|
|
56 |
|
RadixItem *ri=rs->six2four[s][t]->next; |
|
57 |
|
while(ri) { |
|
58 |
|
result[i++]=ri; |
|
59 |
|
ri=ri->next; |
|
60 |
|
} |
|
61 |
|
} |
|
62 |
|
} |
|
63 |
|
} while(--t>=0); |
|
64 |
|
} while(--s>=0); |
|
65 |
|
return result; |
|
66 |
|
} |
|
67 |
|
|
|
68 |
|
return NULL; |
|
69 |
|
} |
|
70 |
|
|
|
71 |
|
RadixItem *radix_cut(RadixSorter *rs, unsigned key, void *data) { |
|
72 |
|
if(key<=rs->maxValue) { |
|
73 |
|
double d = ((double) key)/1000.0; |
|
74 |
|
unsigned six2four = (unsigned)trunc(d); |
|
75 |
|
unsigned three2zero=key-six2four*1000; |
|
76 |
|
|
|
77 |
|
if(rs->six2four[six2four]) { |
|
78 |
|
RadixItem *ri=rs->six2four[six2four][three2zero]; |
|
79 |
|
RadixItem *lastRi=NULL; |
|
80 |
|
while(ri->data!=data) { |
|
81 |
|
if(ri->next) { |
|
82 |
|
lastRi=ri; |
|
83 |
|
ri=ri->next; |
|
84 |
|
} else { |
|
85 |
|
break; |
|
86 |
|
} |
|
87 |
|
} |
|
88 |
|
if(ri->data==data) { |
|
89 |
|
if(lastRi) { |
|
90 |
|
lastRi->next=ri->next; |
|
91 |
|
} else { |
|
92 |
|
rs->six2four[six2four][three2zero]=ri->next; |
|
93 |
|
} |
|
94 |
|
ri->next=NULL; |
|
95 |
|
rs->size--; |
|
96 |
|
return ri; |
|
97 |
|
} |
|
98 |
|
} |
|
99 |
|
} |
|
100 |
|
return NULL; |
|
101 |
|
} |
|
102 |
|
|
|
103 |
|
void radixsort_destroy(RadixSorter *rs) { |
|
104 |
|
// TODO destroy RadixItems chains |
|
105 |
|
// TODO destroy three2one segments |
|
106 |
|
// TODO destroy six2four |
|
107 |
|
} |