xaizek / hstr (License: Apachev2) (since 2018-12-07)
Bash and Zsh shell history suggest box - easily view, navigate, search and manage your command history.
Commit 6b8d1564bcab7d8a3ca3278844d341b3d2977f09

Adding hash map and radix sort.
Author: Martin Dvorak
Author date (UTC): 2013-12-15 00:03
Committer name: Martin Dvorak
Committer date (UTC): 2013-12-15 00:03
Parent(s): 273c8456e2c92b9ee6ea7346c589418e6b589883
Signing key:
Tree: f75d304fffcdd988cc4f727ecd8aca1932974edb
File Lines added Lines deleted
src/hashmap.c 67 0
src/include/hashmap.h 27 0
src/include/radixsort.h 23 0
src/radixsort.c 107 0
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 }
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://code.reversed.top/user/xaizek/hstr

Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@code.reversed.top/user/xaizek/hstr

You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a pull request:
... clone the repository ...
... make some changes and some commits ...
git push origin master